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.
   228   229   230   231   232   233   234   235   236   237   238