CS-220, Sec. 90, Week 9-C R. Eckert TIMING ON COMPUTER SYSTEMS Frequently microcomputer systems are used to control other equipment. And in many cases, we need to be able to do things like outputting a voltage pulse of a specified length. Let us assume that we want to output a pulse (a one followed by a zero) lasting t seconds to a given bit of a given output port. The general method would be: output a 1 to the bit of the port wait for t seconds output a 0 to the bit of the port The question then becomes "how do we wait for T seconds?" If we set up a delay loop, know how many computer clock cycles are used in the loop, and know how much time a single clock cycle lasts, we can adjust the number of iterations of the delay loop so that the time consumed is equal to the desired pulse length (t). In other words: t = (total # of clocks used)*(time for 1 cycle) If we know the frequency of the computer's system clock (fclk), the time for one clock cycle (tclk) is just the inverse of that frequency. tclk = 1/fclk So our equation becomes: t = (total # of clocks) * (1 / fclk) And if we know what processor is being used in the computer, we can consult the specification sheets for that processor and obtain the number of clock cycles each instruction in its instruction set takes. As an example, assume we are using a microcomputer with a Pentium processor that is running at a clock frequency of 50 MHz. We wish to output a pulse that lasts 1 millisecond to bit 1 of port 23 on this computer. (Perhaps that bit of that port is connected to a device that requires the 1 millisecond pulse to start running.) If we look at the specification sheets for the Pentium, we can get the following information: instruction number of clocks -------------------------------- mov reg,immed 1 loop 6/5 (6 if branch is taken, 5 if not) out al,immed 12 Now let's write some code. We'll use the loop instruction to implement a delay loop. The only problem is that we need to determine how many iterations will be needed to achieve the 1 millisecond delay. Let us assume that the number of iterations is N (unknown at this time). mov cx,N ;Set up for N iterations of the delay loop mov al,00000010b ;Set bit 1 out 23,al ;the pulse starts here again: loop again ;repeat N times mov al,00000000b ;Clear bit 1 out 23,al ;the pulse ends here Now let's look at how many clock cycles are taken from the moment the pulse starts (after the first out instruction executes) until the moment the pulse ends (after the second out instruction executes: again: loop again -----> 6*(N-1) + 5 clocks (branch taken N-1 times) mov 00000000b --> 1 clock out 23,al -----> 12 clocks Total # of clocks = 6*(N-1)+5 + 1 + 12 = 6*N + 12 Time for one clock = 1/fclk = 1/(50*10^6) Substituting in the equation above (and realizing that the required delay is t = 1 millisecond = 1 * 10^-3) 1*10^-3 = (6*N+12) * 1/(50*10^6) In all practical cases, 6*N >> 12, so this becomes 1*10^-3 = 6*N/(50*10^6) We can easily solve this for N. The result, for this example, is: N = 8333 iterations. If we use this number for N in the above program fragment, a pulse of the desired duration will be output. In general if we are using a processor running at a frequency fclk and have a loop instruction that takes C clocks for each iteration and repeats N times, a delay of duration T can be obtained by solving for N in the following equation: t = C*N/fclk GENERATING SOUND (MUSICAL TONES) WITH THE SPEAKER OF A PC A sound is nothing more than a wave. The pitch of the sound is determined by its frequency. We can emulate a sound wave by sending out a square wave. This is nothing more than an alternating series of 1's and 0's. We can determine the pitch of the sound by adjusting the delay time between each 1 and zero. The following diagrams show different square-wave "sound" signals. __________ __________ __________ __________| |__________| |__________| |_______ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___| |___| |___| |___| |___| |___| |___| |___| |___| |_ The second one would have a higher pitch (frequency) than the first. All IBM-PC compatible computers contain a speaker. The speaker is wired as shown below: Bit-1, Port 61h -----------------> AND ---------> SPEAKER --> GATE | Bit-0, Port 61h ---> Timer/ -- Oscillator We can generate a sound in one of two ways: 1. Set the upper input to the AND gate to 1, set the timer/oscillator to generate a square wave of the appropriate frequency (this may be done by outputting the correct information to the timer/oscillator control ports-- ports 40h-43h), and start the timer/oscillator by outputting a 1 to its input. 2. Turn off the timer/oscillator so that its output is always high (by outputting a 0 to its input), and send alternating 1's and 0's to the upper input to the AND gate. The programmed delay between each 1 and 0 will determine the frequency (pitch) of the sound produced. We will look in detail at method 2. The following pseudo-code could be used to generate an unending sound. Input from Port 61h Turn off Bit 0 (without affecting the other bits) top: Output to Port 61h Toggle bit 1 (without affecting the other bits) --> 101010... Delay (the duration of the delay loop determines the pitch) jmp top The following is a closeup of one complete sound wave: _________________________ __ __| |_________________________| |<------------------------------------------------->| P P is the period of the sound wave, and this is equal to the inverse of its frequency. If we want to output a sound wave with a frequency ftone, we need to output a 1, wait for P/2, then output a 0, wait for P/2, and repeat the procedure. The delay time of each of these "pulses" is P/2, or, in other words, 1/(2*ftone). The code we might use to output an unending sound wave: in al,61h ;get contents of port and al,11111110b ;turn off bit 0 top: out 61h,al ;next pulse (half wave) mov cx,N ;N depends on fclk and ftone delay: loop delay ;delay proper amount of time xor al,00000010b ;toggle bit 1 jmp top ;do it again The value of N will determine the frequency of the sound. Using the same equation we used at the beginning of this unit and assuming that the processor is a pentium, we have for the delay: t = 6*N/fclk But, the required delay t = P/2 = 1/(2*ftone). Substituting this, and solving for N, we get: N = fclk/(12*ftone) If, for example, we wanted to output a "middle-C" (ftone = 264 Hz) on a PC running at 50 MHz (fclk = 50000000) with a Pentium processor, the equation gives N = 15783.