Kittu20
Member level 2
Hello everyone,
I'm interested in understanding the potential reasons why processors can experience delays when executing ISR (Interrupt Service Routine) code and how we can determine if the processor is indeed getting delayed during ISR execution. I have written interrupt code for my microcontroller to generate a 1ms timer interrupt. For simplicity, I have removed some unnecessary parts of the code. Here's my simplified code for generating the 1ms timer interrupt for reference.
I have this question because I came across the term "interrupt latency" and I read that due to interrupt latency, processors can experience delays in executing ISR. Can you provide information into the factors that might lead to such delays and suggest methods or tools for monitoring and detecting these delays in ISR execution?
I'm interested in understanding the potential reasons why processors can experience delays when executing ISR (Interrupt Service Routine) code and how we can determine if the processor is indeed getting delayed during ISR execution. I have written interrupt code for my microcontroller to generate a 1ms timer interrupt. For simplicity, I have removed some unnecessary parts of the code. Here's my simplified code for generating the 1ms timer interrupt for reference.
I have this question because I came across the term "interrupt latency" and I read that due to interrupt latency, processors can experience delays in executing ISR. Can you provide information into the factors that might lead to such delays and suggest methods or tools for monitoring and detecting these delays in ISR execution?
C:
#define _XTAL_FREQ 8000000
// PIC18F45K80 Configuration Bit Settings
// CONFIG1L
#pragma config RETEN = OFF // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = HIGH // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF // Extended Instruction Set (Disabled)
// CONFIG1H
#pragma config FOSC = INTIO2 // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF // Internal External Oscillator Switch Over Mode (Disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3 // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer (WDT disabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576 // Watchdog Postscaler (1:1048576)
// CONFIG3H
#pragma config CANMX = PORTB // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7 // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON // Master Clear Enable (MCLR Enabled, RE3 Disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K // Boot Block Size (2K word Boot Block size)
// CONFIG5L
#pragma config CP0 = OFF // Code Protect 00800-01FFF (Disabled)
#pragma config CP1 = OFF // Code Protect 02000-03FFF (Disabled)
#pragma config CP2 = OFF // Code Protect 04000-05FFF (Disabled)
#pragma config CP3 = OFF // Code Protect 06000-07FFF (Disabled)
// CONFIG5H
#pragma config CPB = OFF // Code Protect Boot (Disabled)
#pragma config CPD = OFF // Data EE Read Protect (Disabled)
// CONFIG6L
#pragma config WRT0 = OFF // Table Write Protect 00800-01FFF (Disabled)
#pragma config WRT1 = OFF // Table Write Protect 02000-03FFF (Disabled)
#pragma config WRT2 = OFF // Table Write Protect 04000-05FFF (Disabled)
#pragma config WRT3 = OFF // Table Write Protect 06000-07FFF (Disabled)
// CONFIG6H
#pragma config WRTC = OFF // Config. Write Protect (Disabled)
#pragma config WRTB = OFF // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF // Data EE Write Protect (Disabled)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protect 00800-01FFF (Disabled)
#pragma config EBTR1 = OFF // Table Read Protect 02000-03FFF (Disabled)
#pragma config EBTR2 = OFF // Table Read Protect 04000-05FFF (Disabled)
#pragma config EBTR3 = OFF // Table Read Protect 06000-07FFF (Disabled)
// CONFIG7H
#pragma config EBTRB = OFF // Table Read Protect Boot (Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
__bit timeFlag = 0;
//volatile int timeFlag = 0;
volatile unsigned char seconds = 0;
// Calculate Reload_Value for 1ms with a 20 MHz oscillator and prescaler 8
#define Reload_Value 625 // (20,000,000 XTAL / 4 / 8 prescale) = 625
void initializeTimer1() {
// Configure Timer1 in 8-bit mode with a prescaler of 8
T1CON = 0b00110000; // mode 0x08 interrupt, CCP1 pin hi on ==
// Configure CCP module
// CCP1CON = 0b00001011; // 0x0B
CCP1CON = 0b00001000; // 0x08
// Load the high and low bytes of Reload_Value into CCPR1
CCPR1 = Reload_Value;
// CCPR1H = (Reload_Value >> 8); // Load high byte of Reload_Value
// CCPR1L = (Reload_Value & 0xFF); // Load low byte of Reload_Value
// Clear Timer1 registers
TMR1H = 0;
TMR1L = 0;
// Clear Timer1 interrupt flag
// TMR1IF = 0;
// Clear CCP1 interrupt flag
CCP1IF = 0;
// Start Timer1 and CCP module
TMR1ON = 1;
CCP1IE = 1; // Enable CCP1 interrupt
}
void main() {
// Initialize Timer1
initializeTimer1();
// Initialize INTCON register
INTCON = 0; // Clear INTCON register
// Enable global and peripheral interrupts
INTCONbits.PEIE = 1; // Peripheral Interrupt Enable
INTCONbits.GIE = 1; // Global Interrupt Enable
while (1) {
// Check if the timeFlag is set (1ms interval)
if (timeFlag) {
// Increment seconds
seconds++;
// Reset the timeFlag to indicate that the 1ms interval has been processed
timeFlag = 0;
}
}
}
void __interrupt() ISR() {
if (CCP1IF){
// Clear the CCP1 interrupt flag
CCP1IF = 0;
// advance COMPARE value
CCPR1 += Reload_Value;
timeFlag = 1; // Notify main routine
}
}