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.
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:
- 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
- IPEN: Interrupt Priority Enable bit. Enables priority levels when set.
Interrupt control register
- 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
- TMR0IE: TMR0 Overflow Interrupt Enable bit. Enables the TMR0 overflow interrupt
- INT0IE: INT0 External Interrupt Enable bit. Enables the INT0 external interrupt
- RBIE: RB Port Change Interrupt Enable bit. Enables the RB port change interrupt
- TMR0IF: TMR0 Overflow Interrupt Flag bit. Sets when TMR0 register has overflowed
- INT0IF: INT0 External Interrupt Flag bit. Sets when INT0 external interrupt occur
- RBIF: RB Port Change Interrupt Flag bit. Sets when at least one of the RB7: RB4 pins change state
- INTEDGx: External Interrupt x Edge Select bit.
- If set Interrupt flag is set on rising edge.
- If cleared Interrupt flag is set on falling edge
- TMR0IP: TMR0 Overflow Interrupt Priority bit. If set, TMRO interrupt is set as a High priority interrupt
- RBIP: RB Port Change Interrupt Priority bit. If set, RB Port Change Interrupt is set as a High priority interrupt
- INTxIP: INTx External Interrupt Priority bit. If set, INTx External Interrupt is set as a High priority interrupt
- INTxIE: INTx External Interrupt Enable bit. Enables the INTx external interrupt
- INTxIF: INTx External Interrupt Flag bit. The bit sets when INTx external interrupt occurs
PERIPHERAL INTERRUPT REQUEST (flag)
- 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
- 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
- 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
- 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
- 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
- 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.