0
0
Power-electronicsHow-ToBeginner · 4 min read

Generate Delay Using Timer Interrupt in Embedded C

To generate a delay using timer interrupt in Embedded C, configure a hardware timer to trigger an interrupt after a set time interval, then count the interrupts in the interrupt service routine until the desired delay is reached. This method allows the CPU to perform other tasks while waiting, making it efficient for embedded systems.
📐

Syntax

To use a timer interrupt for delay, you typically:

  • Initialize the timer with a specific count value.
  • Enable the timer interrupt.
  • Write an Interrupt Service Routine (ISR) to handle the timer overflow.
  • Use a counter variable to track elapsed time.

Each microcontroller has its own timer registers and interrupt vectors, but the general pattern is similar.

c
void Timer_Init(void) {
    // Set timer count for desired interval
    TIMER_REG = TIMER_START_VALUE;
    // Enable timer interrupt
    TIMER_INTERRUPT_ENABLE = 1;
    // Start timer
    TIMER_START = 1;
}

void Timer_ISR(void) {
    // Clear interrupt flag
    TIMER_INTERRUPT_FLAG = 0;
    // Increment delay counter
    delay_counter++;
}
💻

Example

This example shows how to generate a 1-second delay using a timer interrupt on a generic microcontroller. The timer interrupt triggers every 10 ms, and the ISR counts 100 interrupts to reach 1 second.

c
#include <stdint.h>
#include <stdbool.h>

volatile uint32_t delay_counter = 0;
volatile bool delay_done = false;

// Assume timer interrupt every 10 ms
void Timer_Init(void) {
    // Configure timer registers for 10 ms interval
    TIMER_REG = TIMER_START_VALUE;  // Set timer start value
    TIMER_INTERRUPT_ENABLE = 1;    // Enable timer interrupt
    TIMER_START = 1;               // Start timer
}

// Timer Interrupt Service Routine
void Timer_ISR(void) {
    TIMER_INTERRUPT_FLAG = 0;      // Clear interrupt flag
    delay_counter++;
    if (delay_counter >= 100) {    // 100 * 10ms = 1 second
        delay_done = true;
        TIMER_START = 0;           // Stop timer
    }
}

void delay_1s(void) {
    delay_counter = 0;
    delay_done = false;
    Timer_Init();
    while (!delay_done) {
        // Wait here or do other tasks
    }
}

int main(void) {
    // Initialize hardware
    // ...
    delay_1s();
    // Continue with rest of program
    while(1) {}
}
⚠️

Common Pitfalls

  • Not clearing the interrupt flag: Forgetting to clear the timer interrupt flag inside the ISR causes repeated interrupts.
  • Using blocking loops: Busy-waiting inside the ISR or main loop wastes CPU cycles.
  • Incorrect timer configuration: Wrong timer count or prescaler leads to inaccurate delays.
  • Not declaring shared variables volatile: The compiler may optimize out variables changed in ISR if not marked volatile.
c
/* Wrong: Missing interrupt flag clear */
void Timer_ISR(void) {
    delay_counter++;
}

/* Right: Clear interrupt flag */
void Timer_ISR(void) {
    TIMER_INTERRUPT_FLAG = 0;
    delay_counter++;
}
📊

Quick Reference

Tips for using timer interrupts for delay:

  • Configure timer for the smallest practical interval.
  • Use a counter in ISR to accumulate delay.
  • Mark shared variables volatile.
  • Clear interrupt flags inside ISR.
  • Stop timer when delay completes to save power.

Key Takeaways

Configure hardware timer and enable its interrupt to generate periodic events.
Use an interrupt service routine to count timer events and track elapsed time.
Always clear the timer interrupt flag inside the ISR to avoid repeated triggers.
Declare variables shared between ISR and main code as volatile to prevent optimization issues.
Stop the timer after the delay to save power and avoid unnecessary interrupts.