The basic operations of interrupt service are broadly carried out by 4 phases.
The first is the part that requests the interrupt, the second is the interrupt request flag, the third is the interrupt controller that controls the interrupt, and the fourth is the CPU that actually executes the interrupt service.
An interrupt is serviced via these 4 phases.
[Interrupt request source]
Parts that request interrupts include the timer block, serial block, and external signal edge detector (these parts differ depending on the device).
Once an interrupt request condition, such as a timer match or completion of serial data reception, has been met, the corresponding interrupt request flag is set in these parts.
The first phase of interrupt service involves the satisfaction of a specified condition in each peripheral function block.
When a condition such as a match with a compare register in the timer block, completion of communication in the serial block, or detection of an edge via an external interrupt is satisfied, the corresponding interrupt request flag is set.
Interrupt request flags can also be set by program.
[Interrupt request flag]
In this way, each interrupt request source simply sets the corresponding interrupt request flag. The interrupt request source and interrupt controller operate independently.
The interrupt request flag is what connects these two parts.
Note that there is only one interrupt request flag (1 bit) for each interrupt source.
Therefore, even if the same interrupt request occurs more than once before the interrupt is acknowledged, it will only be recognized as having occurred once.
Interrupt request flags can also be set and cleared by program.
When using this function, all UART transmission processing, including transmission of the first data, can be executed via interrupts.
In this case, however, be sure to set the relevant interrupt request flag using a bit manipulation instruction.
Example of UART transmission processing |
When transmitting multiple bytes of data, the main program usually writes the first byte of the output data to UART, and at the same time, information on the second and subsequent bytes of data is passed to the interrupt service program.
The interrupt service program then writes the second and subsequent bytes of data to UART based on the information passed from the main program.
The processing therefore differs between the first and subsequent bytes of data.
The main program passes the information on the transmit data to the interrupt service program and set the interrupt request flag.
All of the processing to actually write data to UART is carried out by the interrupt service program, so the entire processing flow is more visible.
Operations subsequent to the interrupt request flag are executed by the interrupt controller.
Whether to enable (not mask) or disable (mask) an interrupt request flag is determined by the interrupt controller according to the setting of the interrupt mask register.
An interrupt request flag that has been set to disabled is ignored in all subsequent operations.
However, because the request flag itself is not cleared, once the mask is cancelled, the interrupt request becomes enabled again from that point.
Unmasked interrupt requests are sent to the standby controller and are used for releasing standby (except when the macro service in the 78K4 is used).
Interrupt requests are also sent to the CPU via the interrupt priority circuit.
When the CPU receives an interrupt, the corresponding interrupt request flag is cleared.
If the CPU is in the interrupt-disabled state, the received interrupt is simply used to release standby (if the system is not in the standby state, the interrupt is simply held pending).
If the CPU is in the interrupt-enabled state, vector interrupt service is executed after standby is released.
Note that when the macro service in the 78K4 is used, interrupts are received even if the CPU is in the interrupt-disabled state, and are serviced by the macro service function.
Interrupt request flags can be used in the following three ways.
The interrupt priority circuit compares the priority level of interrupt requests generated at the same time, as well as the priority of the interrupt currently being serviced.
Consequently, the interrupt controller monitors the status of the interrupt currently being executed by the CPU, and judges that interrupt service is "in progress" until the RETI instruction is executed.
In the case of the 78K4 and 78K0, while an NMI is being executed, an interrupt with a lower priority cannot be acknowledged even if the CPU executes the EI instruction.
If the CPU is in the interrupt-enabled state, it acknowledges the interrupt with the highest priority (as determined by the interrupt priority circuit), saves the PC and PSW values to the stack, and branches to the interrupt vector.
At this time, the corresponding interrupt request flag is cleared and the CPU enters the interrupt-disabled state.
Note that the timing at which the CPU acknowledges an interrupt and branches to the interrupt vector differs depending on the execution state of the instruction.
So it is not always the same.
This timing varies greatly if an interrupt request hold instruction is executed, or if there is a period in which interrupts are disabled.
Consequently, if the exact timing is needed, you should use hardware functions such as the timer output function or real-time output function instead of interrupt service.
Once interrupt service is completed, the program returns to the original processing via the RETI instruction.
At this time, the original value before interrupt acknowledgment is written back to the PSW, so there is no need to execute the EI instruction immediately before executing the RETI instruction.