Maintain precise timing with PC's speaker logic

DS Oberoi, CEDTI, and Harinder Dhingra, GCET, Jammu, India -- 7/11/2002

Precise timing control is paramount in data acquisition and analysis and especially in digital-signal processing. The easiest way of maintaining timing control in a PC is to use delay loops. The disadvantage of this implementation is that the delay loop's elapsed time depends on the system's operating frequency. Hence, a program works accurately with a single operating frequency, but you must modify it for other frequencies. You can use add-on cards to achieve timing control, but they're costly, and, for simple operation, they remain underused. This Design Idea explores another way to obtain timing control. You can implement a stable delay loop with the aid of the PC's speaker logic. In PC/AT architecture, a 16-bit 8255 timer/counter IC is available, and the IC's operating frequency of 1.1931817 MHz is fixed across the entire range of PC families. You can use this fixed-frequency feature to implement a delay loop.

In PC/AT architecture, Counter 0 serves as a system timer and to maintain the time of day. Counter 1 generates pulses and serves as the DRAM refresh-rate generator. The PC uses Counter 2 for sound generation through the PC's speaker. Only Counter 2 is available for an implementation of the delay loop. You can enable or disable Counter 2 by setting bit 0 of the 8255's Port B to 1 or 0, respectively. For our purposes, Counter 2 operates as a rate generator (in Mode 2 operation). In this mode, the counter automatically decrements by one count with every counter clock pulse (1/1.1931817 MHz=0.838095 µsec= counter_count_time). Hence, the total period that Counter 2 can measure is approximately 54.92 msec (65,536×0.838905 µsec). Listing 1 gives the details of implementing the delay loop.

The software sets Counter 2 to operate in Mode 2 by setting the control-word value to 0b4h and by writing this control-word data to the control-register port (043h). A routine called delay_loop() actually implements the delay loop. The routine first configures Counter 2 by writing the control word in the control register. Then, the program loads Counter 2 with starting (ffffh) data at address 042h in a 2-byte operation. The routine then enables the counter by setting bit 0 of the 8255's port B (in other words, port 61h) to one. Once enabled, Counter 2 automatically decrements by one count every 0.8380958 µsec. Before calling the delay routine, the software computes the total of Counter 2's count required for the desired delay (desired_delay_time). A "while" loop repeatedly reads back Counter 2's data from its input port (042h) in a 2-byte operation.

ADVERTISEMENT
The two bytes combine to produce 16-bit data (counter_data). This data helps to compute the elapsed counts (count_elapsed); as soon as the required count is reached, the software exits this loop. The routine disables Counter 2 by setting bit 0 of the 8255's port B to 0 before returning to the calling program. Thus, it achieves the desired delay. Because the count depends on a fixed operating frequency across the entire PC family, you can use this method to implement a precise and stable timing loop. You can achieve delays of approximately 20 µsec to 54.9 msec. The software is in Turbo C++ and assembly language and was tested it in MS-DOS mode on a 450-MHz Pentium II computer.

Is this the best Design Idea in this issue? Select at www.ednmag.com.


© 2009, Reed Business Information, a division of Reed Elsevier Inc. All Rights Reserved.