0
0
Power-electronicsDebug / FixBeginner · 4 min read

How to Handle Multiple Interrupts in Embedded C Correctly

To handle multiple interrupts in embedded C, assign each interrupt a unique ISR (Interrupt Service Routine) and configure interrupt priorities if supported. Use volatile variables and clear interrupt flags inside each ISR to avoid conflicts and ensure proper execution.
🔍

Why This Happens

When multiple interrupts occur, if ISRs are not properly separated or interrupt flags are not cleared, the system may behave unpredictably or miss interrupts. This happens because the microcontroller might not know which interrupt to handle first or may keep re-entering the same ISR.

c
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int count1 = 0;
volatile int count2 = 0;

ISR(INT0_vect) {
    count1++;
    // Missing flag clear or improper handling
}

ISR(INT1_vect) {
    count2++;
    // Missing flag clear or improper handling
}

int main(void) {
    // Enable INT0 and INT1 interrupts
    EIMSK |= (1 << INT0) | (1 << INT1);
    sei();
    while(1) {
        // Main loop
    }
    return 0;
}
Output
System may miss interrupts or behave unpredictably due to improper flag clearing and no priority handling.
🔧

The Fix

Assign separate ISRs for each interrupt and clear the interrupt flags inside each ISR. If your microcontroller supports interrupt priorities, configure them to decide which interrupt runs first. Use volatile variables to safely share data between ISRs and main code.

c
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int count1 = 0;
volatile int count2 = 0;

ISR(INT0_vect) {
    count1++;
    EIFR |= (1 << INTF0); // Clear INT0 interrupt flag
}

ISR(INT1_vect) {
    count2++;
    EIFR |= (1 << INTF1); // Clear INT1 interrupt flag
}

int main(void) {
    // Configure INT0 and INT1 as needed
    EIMSK |= (1 << INT0) | (1 << INT1); // Enable INT0 and INT1
    sei(); // Enable global interrupts
    while(1) {
        // Main loop can use count1 and count2 safely
    }
    return 0;
}
Output
Interrupts handled correctly with counts incremented and flags cleared.
🛡️

Prevention

To avoid issues with multiple interrupts, always:

  • Use separate ISRs for each interrupt source.
  • Clear interrupt flags inside each ISR to prevent repeated triggers.
  • Use volatile for variables shared between ISRs and main code.
  • Configure interrupt priorities if your hardware supports it to control execution order.
  • Keep ISRs short and efficient to avoid blocking other interrupts.
⚠️

Related Errors

Common related errors include:

  • Interrupt nesting issues: Not enabling nested interrupts when needed can block higher priority interrupts.
  • Race conditions: Accessing shared variables without volatile or atomic operations causes inconsistent data.
  • Interrupt flag not cleared: Causes the ISR to be called repeatedly, freezing the system.

Key Takeaways

Assign unique ISRs for each interrupt source to avoid conflicts.
Always clear interrupt flags inside the ISR to prevent repeated triggers.
Use volatile variables for data shared between ISRs and main code.
Configure interrupt priorities to control which interrupt runs first.
Keep ISRs short and efficient to allow smooth handling of multiple interrupts.