The low order bit of the control word gives us the ability to specify the initial count value (the
frequency divisor) as a 16-bit binary number (0001h-10000h) or as a BCD (binary coded
decimal) number in the range of 1-10000. The data sheet also specifies that a value of all zeros
written to the counter signifies the largest number in the range of possible count values. This
explains how it is possible to represent 10000h with only 16 bits. Binary coded decimal
representation uses 4-bit groups to encode each digit of a decimal number. For example, the
binary coded decimal representation of 937 is 1001 0011 0111. To specify a binary coded
decimal number in a program, you should be able to see that a hex representation is appropriate.
That is, if you wanted to use 937 BCD as an immediate operand in an assembly language
instruction, you would use 937h. In some programs such as financial applications, using BCD
representation is more natural than other representations.
The RL bits allow control over the reading and writing of the counter value for a particular
counter. The "counter latching operation" code transfers the current count to an internal storage
buffer so that the count is stable for reading (otherwise, the continued countdown could change
the value of the counter during the read). The other modes specify which part of the initial count
value is to be written or read. It is important to realize that the initial count value is a 16-bit
number, whereas the counter registers are only eight bits wide. This means that the programmer
must read or write the counter register in two instructions. The usual method is to use RL mode
11. In this case, the programmer reads or writes the least significant byte first. If the operation is
a write, the internal logic of the timer transfers this byte to an internal register, so that the next
write does not destroy its value. After reading or writing the least significant byte, the
programmer uses a second instruction to read or write the most significant byte. Finally, the SC
bits allow the programmer to specify which counter he or she is reading or writing.
With this information, we are ready to program the timer to function in a manner that will be
appropriate for our example application. As we mentioned above, we will want to use mode 0, so
we already know that the control byte bits 1, 2, and 3 must be cleared. We will use a binary
number as the initial counter value, so bit 0 must also be 0. We will use a two-byte counter, so
this determines that the RL bits must be 11. Finally, we arbitrarily decide to use counter 1, so this
gives us 01 as the value for bits 6 and 7. Putting these bits together gives us 01110000b (70h) as
the value we must write to the control register.
The next step is to determine the initial count value. If we assume that we are interfacing with a
clock speed of 8 KHz, then that gives us the frequency on the CLKn inputs. Suppose we decide
that we want a time slice to be 500 milliseconds (this is quite long for a time slice, but consider
that we are working with a slow processor!). Recall that one hertz is one cycle per second, so a
period of 500 milliseconds gives a frequency of 0.5 hertz. Of course 8KHz is 8000 hertz. The
problem is to determine the appropriate divisor so that the OUT signal will go high to generate
an interrupt every 500 milliseconds: 8000/0.5 = 16000 = 3E80h.
We now have the values necessary to program the timer. The only remaining step is to determine
the addresses for each of the ports on the timer. We know that the base address is 80h, so we
really only need the relative ordering of the ports. The data sheet will give us this information: