Page 204 - Programming Microcontrollers in C
P. 204
Timers 189
other interrupt can be serviced while the microcontroller is executing an
interrupt service routine. This operation does not lead to missed inter
rupts, but it can cause an inordinate delay in service of an interrupt.
In some cases, it is possible that data might be lost if an interrupt
is not handled expeditiously. For example, a high-speed serial port
might notify the microcontroller that its receiving data buffer is full
by an interrupt when the interrupt is disabled. In such a case, if the
interrupt service routine being executed is not completed before the
next serial data are received, the data in the buffer will be lost.
Sometimes it is necessary to pass data between the applications
portion of the program and the interrupt service routine. These data
can be stored in global memory, and both routines can access them.
Here is a case where you must examine the assembly code generated
by the compiler to make certain that no problems will be generated
in passing of data between these routines. Problems can be created
by passing information this way, but they can be avoided if the pro
gram rigorously avoids loading data that is changed in an interrupt
service routine into a register in the application section of the pro
gram. We will see instances of this problem later.
If you go back to Listing 4-4, you’ll see that the program organi
zation discussed above is also used. This organization will be found
for every program in this book. We will refer to the initialization, the
applications, and the asynchronous service sections of the program.
This arrangement works quite well, and is reliable. There should be
a strong justification if alternate program forms are to be used.
When programming the 15-bit timer, we found that asking a com
piler designed specifically for an 8-bit machine to work in 16-bit
quantities often created unwieldy code. A programmer, however, does
not always have the freedom to work with 8-bit quantities only. All of
the time registers in this system are 16 bits wide, and the time values
contained in these registers must be processed. These registers are al
ways located in two adjacent 8-bit memory locations. One method for
handling the 8/16-bit dichotomy is to use a union. The code sequence
struct bothbytes
{
int hi;
int lo;
};