Page 233 - Programming Microcontrollers in C
P. 233
218 Chapter 5 Programming Large 8-Bit Systems
occurrence of an interrupt. The bits in these registers are turned off
when the code instructs the bit to be set. Since these two registers are
so different from the remainder of the registers in the system, I handle
them differently. Rather than declare a structure for these registers,
the individual bits are #defined as power-of-two values. Therefore,
the bit OC2F is defined as 0x40 and the bit IC2F is #defined as
0x02. The flag1 register TFLG1 is forced to the address
Register_Set+0x23. Now to clear the bit OC2F, you need to set
TFLG1=OC2F;
The final section of the file contains several macros that are helpful
in handling interrupt service routines. The first macro is
#define vector(a,b) ((*(void **)b) = (a))
This macro is used to place the address of an interrupt service
routine into a vector address. The argument ais a pointer to the interrupt
service routine, and b is the vector address. If one asks what b is, you
must say that b is a pointer to a location that contains the address of the
interrupt service routine. The interrupt service routine address is also a
pointer to function that has no (void) return. Therefore, the vector
address is a pointer to a pointer to the type void and must be cast as
such before it can be used. This value must be dereferenced to be able
to place the address of the interrupt service routine into it. You can use
the macro vector(a,b)to place the address of each interrupt service
routine used into the proper vector location.
This macro will create code that copies the address of an interrupt
service routine to the specified memory location. This operation is
needed whenever the vector table is stored in RAM, so that the vector
table must be rebuilt each time the microcontroller is powered up.
Another approach must be used to place interrupt service routine
addresses in the vector table when this table is contained in ROM. This
latter case is probably more common than the former. In this case, we
are trying to fill a memory array with the values of the addresses of the
several interrupt service routines that the program might use. One way
to do this operation is to build an array that contains these addresses,
compile this array, and then at link time force the array to be linked to
the memory location corresponding to the beginning of the vector table.
Consider the following code sequence.