Page 354 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 354
11,6 Interrupt Synchronization 331
Some points about the interrupt sequence must be stressed. As soon as it honors an
interrupt seen on a line, the 6812, like most computers, sets the I condition code bit to
prevent honoring another interrupt from the same device. If it didn't, the first instruction
in the handler would be promptly interrupted—an infinite loop that will fill up the stack.
You do not have to worry about returning it to its value before it was changed, because
step 6 restores the program counter and the condition code register and its I bit to the
values they had before the interrupt was honored. However, a handler can change that
level using a TFR,AND,orOR to condition code instruction to permit honoring
interrupts. Note that the I/O device is generally still asserting its interrupt request line
because it doesn't know what is going on inside the microprocessor. If the RTI is
executed or I is otherwise cleared, this same device will promptly interrupt the processor
again and again—hanging up the machine. Before the handler executes RTI or changes I,
it must remove the interrupt source! (Please excuse our frustration, but this is so simple
yet so much of a problem.)
To handle the interrupts, we need to put the handler's address in the 16-bit word at
Oxffee. The mechanism that puts an interrupt handler's address where the interrupt
mechanism needs to find it is specific to each compiler. In a compiler that is specifically
designed for I/O interfacing, all we need to do is write interrupt 8 in front of the name
of the procedure for counter/timer device 0 (a number different from 8 is used for other
devices—see Table 11.1). This convention inserts the address of the handler into Oxffee,
and further ends the procedure with an RTI. For other compilers a statement * (int
*) Oxffee = (int) handler; puts the address of the handler in the location that the
hardware will use when an interrupt occurs. However, this location is in EEPROM in
the ' A4 and flash in the 'B32, so special programming procedures are used.
There are two parts of the path that an interrupt request takes. In our example, the
counter/timer flag is set if an edge occurs on its input. A switch in series with an input
that can set this flag is called an arm; if it is closed the device is armed, and if it is
opened, the device is disarmed. Any switch between the flag register and the 6812
controller is called an enable; if all such switches are closed the device is enabled, and if
any are opened, the device is disabled. Arming a device lets it record a request and makes
it possible to request an interrupt, either immediately if it is enabled or later if it. is
disabled. You disarm a device if you do not want to honor an interrupt now or later. But
you disable an interrupt to postpone it. You disable an interrupt if you can't honor it
now, but you may honor it later when interrupts are enabled.
Also, for gadfly synchronization, you arm the device so the flag register can become
set when the device enters the DONE state, but you do not enable the interrupt because
the program has to test the flag. If an interrupt did occur and was honored properly so as
not to crash the computer, the gadfly loop wouldn't exit because the flag would be
cleared in the handler before the gadfly loop could test it and exit its loop.
We illustrate the use of interrupt synchronization by implementing a variation of
the Geiger counter that used gadfly synchronization. Each time a pulse occurs, PORTT
bit 0 sees a rising edge, which causes an interrupt. To count the pulses, execute the C
procedure