An interrupt is a signal to a processor, generated by hardware or software, of the occurrence of a particular event. The processor receiving the interrupt signal and requested to stop the current execution sequence and attend to a different code sequence called the interrupt vector or Interrupt Service Routine( ISR ). After executing the ISR, the previous execution of sequence is resumed. The processor may choose to ignore or act on the request according to the configuration set by the programmer with the help of registers.
Interrupts in PIC18F4550
There are 2 types of interrupts based on origin Software Interrupt: It comes from a program that is executed by a microcontroller or by internal peripherals of the microcontroller. Hardware Interrupt: These interrupt requests are sent by external hardware devices connected to certain pins of the microcontroller.
Interrupts could also be classified based on their priority High priority Interrupt: These interrupts cannot be interrupted. A high priority interrupt vector is located at 0008h in the program memory. Low priority Interrupt: These interrupts itself could be interrupted by high priority interrupts and its interrupt vector is located at 0018h.
The interrupt used in PIC18f4550 are edge triggered and the edge trigger could be configured as a rising edge or falling edge.
Steps for executing an Interrupt request
In general, on receiving a valid interrupt request, the processor does the following steps to execute the ISR
Finished current instruction execution.
Stores the next instruction address (Program Counter) and the current status in the Stack memory.
Jumps to a fixed memory location called Interrupt vector table which contains the address of the ISR.
Jumps to the ISR address obtained from the Interrupt vector table.
Executes all instructions in the ISR.
Upon exiting the ISR, restores the program counter and the status, as before interrupt request, from the stack.
Continues executing the initial instruction sequence.
The processor will automatically follow these steps once the interrupt control registers are properly configured and the ISR is defined.
Interrupt Handling
PIC18F4550 can handle multiple interrupt request and treat them based on priority. The configuration and functioning of interrupts are done with the help of the registers:
RCON
INTCON
INTCON2
INTCON3
PIR1, PIR2
PIE1, PIE2
IPR1, IPR2
The main functionality of these registers is to store configuration bits for each interrupts. These bits are:
Enable bits: To enable a specific interrupt request. A processor will branch to its ISR only if the interrupt is enabled.
Priority bits: To specify the priority of a particular request, to set as High priority or Low priority.
Flag bits: Bits set when the particular interrupt request is received.
The high priority signals are located at program memory location 008h and the low priority signals at 018h. If the priority is disabled, by default, all the interrupts branch to 008h memory location. Once the execution reaches the ISR, the interrupt is determined by polling the interrupt flags and associated code sequence is executed. After execution of code, the flag bit must be cleared in software to avoid recursion.
Registers associated with Interrupt
Now, let’s analyze each register used for interrupt handling. We will focus only on bits relevant to interrupt handling in each register.
Reset control register
RCON
IPEN: Interrupt Priority Enable bit. Enables priority levels when set.
Interrupt control register
INTCON
GIE/GIEH: Global Interrupt Enable bit
When IPEN is disabled, GIE enables all interrupts
When IPEN is enabled, GIEH enables all high priority interrupts
PEIE/GIEL: Peripheral Interrupt Enable bit
When IPEN is disabled, PEIE enables all peripheral interrupts
When IPEN is enabled, GIEL enables all low priority interrupts
INTxIF: INTx External Interrupt Flag bit. The bit sets when INTx external interrupt occurs
PERIPHERAL INTERRUPT REQUEST (flag)
PIR1
SPPIF: Streaming Parallel Port Read/Write Interrupt Flag bit, It sets when a read or a write operation has taken place
ADIF: A/D Converter Interrupt Flag bit. It sets when A/D conversion is completed
RCIF: EUSART Receive Interrupt Flag bit. It sets when the EUSART receive buffer, RCREG, is full
TXIF: EUSART Transmit Interrupt Flag bit. It sets when the EUSART transmit buffer, TXREG, is empty
SSPIF: Master Synchronous Serial Port Interrupt Flag bit. It sets when the I2C or SPI transmission/reception is complete
CCP1IF: CCP1 Interrupt Flag bit
TMR2IF: TMR2 to PR2 Match Interrupt Flag. It sets when TMR2 to PR2 match occurred
TMR1IF: TMR1 Overflow Interrupt Flag bit. It sets when TMR1 register overflowed
PIR2
OSCFIF: Oscillator Fail Interrupt Flag bit. The bit sets, when System oscillator fail and clock input, has changed to INTOSC
CMIF: Comparator Interrupt Flag bit. The bit sets when Comparator input is changed
USBIF: USB Interrupt Flag bit. Sets when USB has requested an interrupt
EEIF: Data EEPROM/Flash Write Operation Interrupt Flag bit. Sets when the write operation is complete
BCLIF: Bus Collision Interrupt Flag bit. The bit sets when a bus collision has occurred
HLVDIF: High/Low-Voltage Detect Interrupt Flag bit. The bit sets when a high/low-voltage condition occurred
TMR3IF: TMR3 Overflow Interrupt Flag bit. The bit sets when TMR3 register overflows
CCP2IF: CCP2 Interrupt Flag bit
PERIPHERAL INTERRUPT ENABLE
PIE1:
SPPIE: Streaming Parallel Port Read/Write Interrupt Enable bit
ADIE: A/D Converter Interrupt Enable bit
RCIE: EUSART Receive Interrupt Enable bit
TXIE: EUSART Transmit Interrupt Enable bit
SSPIE: Master Synchronous Serial Port Interrupt Enable bit
CCP1IE: CCP1 Interrupt Enable bit
TMR2IE: TMR2 to PR2 Match Interrupt Enable bit
TMR1IE: TMR1 Overflow Interrupt Enable bit
PIE2:
OSCFIE: Oscillator Fail Interrupt Enable bit
CMIE: Comparator Interrupt Enable bit
USBIE: USB Interrupt Enable bit
EEIE: Data EEPROM/Flash Write Operation Interrupt Enable bit
BCLIE: Bus Collision Interrupt Enable bit
HLVDIE: High/Low-Voltage Detect Interrupt Enable bit
TMR3IE: TMR3 Overflow Interrupt Enable bit
CCP2IE: CCP2 Interrupt Enable bit
All the enable bits in PIE1 and PIE2 will enable their corresponding interrupt if set and will disable if the interrupt is cleared.
PERIPHERAL INTERRUPT PRIORITY
IPR1
SPPIP: Streaming Parallel Port Read/Write Interrupt Priority bit
ADIP: A/D Converter Interrupt Priority bit
RCIP: EUSART Receive Interrupt Priority bit
TXIP: EUSART Transmit Interrupt Priority bit
SSPIP: Master Synchronous Serial Port Interrupt Priority bit
CCP1IP: CCP1 Interrupt Priority bit
TMR2IP: TMR2 to PR2 Match Interrupt Priority bit
TMR1IP: TMR1 Overflow Interrupt Priority bit
IPR2
OSCFIP: Oscillator Fail Interrupt Priority bit
CMIP: Comparator Interrupt Priority bit
USBIP: USB Interrupt Priority bit
EEIP: Data EEPROM/Flash Write Operation Interrupt Priority bit
BCLIP: Bus Collision Interrupt Priority bit
HLVDIP: High/Low-Voltage Detect Interrupt Priority bit
TMR3IP: TMR3 Overflow Interrupt Priority bit
CCP2IP: CCP2 Interrupt Priority bit
All the priority bits in PIR1 and PIR2 will set their corresponding interrupt priority to High if set to 1. These interrupts will have Low priority by default or if priority bit is cleared in priority mode (IPEN=1).
Enabling an Interrupt
Enabling a particular interrupt requires proper configuration of the above-mentioned registers. The required interrupt could be enabled with or without priority by setting or clearing the IPEN( RCON <7> ) bit.
ISR of XC8 compiler as in this format
__interrupt(<type>) void <ISR_identifier> (void)
{
<ISR code sequence>
//Clear the interrupt flag
<Interrupt_flag_bit> = 0;
}
If the priority is disabled
The GIE (INTCON <7>) bit must be first set to enable any interrupt
If the interrupt request is from a peripheral device PEIE (INTCON <6>) must be set
Next set the corresponding interrupt Enable bit of INTCON or PIE registers and clear the Flag bit of INTCON or PIR register.
Next, we should define the ISR with the <type> parameter kept as empty
Clear the corresponding Flag bit after defining the interrupt code sequence.
If the priority is enabled
Set the GIEH bit to enable any of High priority interrupt and set the GIEL bit to enable any of Low priority interrupt.
Set the corresponding Enable bit of INTCON or PIE register.
Define the priority bit in INTCON or IPR registers and clear the Flag bit of INTCON and PIR register.
Next, define the ISR with its priority
For high priority interrupt vector the ISR type used is high_priority
For low priority interrupt vector, the ISR type used is low_priority
At the end of ISR, clear the interrupt flag bit
Note: The default ISR with empty type will occupy the memory location 008h, same as the High priority interrupt. Thus if both the ISR is defined there would be a conflict.
With the interrupt control bits properly configured and their ISR defined, whenever the interrupt request is received, the processor will pause the current code sequence, execute the ISR and return to the previous code sequence being ready to receive the next interrupt signal.