0
0
Power-electronicsHow-ToBeginner · 4 min read

How to Configure Timer Interrupt in Embedded C: Simple Guide

To configure a timer interrupt in embedded C, you need to initialize the timer registers, set the timer count value, enable the timer interrupt, and write an interrupt service routine (ISR) to handle the interrupt. Use timer_init() to set the timer mode and prescaler, enable the interrupt with timer_interrupt_enable(), and define the ISR with the correct interrupt vector.
📐

Syntax

Configuring a timer interrupt typically involves these steps:

  • Initialize Timer: Set timer mode and prescaler.
  • Set Timer Count: Load the timer start value.
  • Enable Interrupt: Turn on timer interrupt in interrupt control registers.
  • Write ISR: Define the interrupt service routine to handle timer events.
embedded_c
void timer_init() {
    // Set timer mode (e.g., CTC mode)
    TCCR0A = (1 << WGM01);
    // Set prescaler to 64
    TCCR0B = (1 << CS01) | (1 << CS00);
    // Set compare value for timer
    OCR0A = 249;
}

void timer_interrupt_enable() {
    // Enable timer compare interrupt
    TIMSK0 = (1 << OCIE0A);
    // Enable global interrupts
    sei();
}

ISR(TIMER0_COMPA_vect) {
    // Code to run on timer interrupt
}
💻

Example

This example configures Timer0 on an AVR microcontroller to generate an interrupt every 1ms assuming a 16 MHz clock. The ISR toggles an LED connected to PORTB0.

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

void timer_init() {
    TCCR0A = (1 << WGM01); // CTC mode
    TCCR0B = (1 << CS01) | (1 << CS00); // Prescaler 64
    OCR0A = 249; // Compare value for 1ms
}

void timer_interrupt_enable() {
    TIMSK0 = (1 << OCIE0A); // Enable compare interrupt
    sei(); // Enable global interrupts
}

ISR(TIMER0_COMPA_vect) {
    PORTB ^= (1 << PORTB0); // Toggle LED
}

int main(void) {
    DDRB |= (1 << DDB0); // Set PORTB0 as output
    timer_init();
    timer_interrupt_enable();
    while(1) {
        // Main loop does nothing, LED toggled in ISR
    }
    return 0;
}
Output
LED on PORTB0 toggles every 1 millisecond
⚠️

Common Pitfalls

Common mistakes when configuring timer interrupts include:

  • Not enabling global interrupts with sei().
  • Forgetting to set the correct timer mode (e.g., CTC mode for compare match).
  • Incorrect prescaler or compare value causing wrong timing.
  • Not defining the ISR with the correct vector name.
  • Modifying shared variables in ISR without volatile keyword or proper synchronization.
embedded_c
/* Wrong: Missing global interrupt enable */
void timer_interrupt_enable_wrong() {
    TIMSK0 = (1 << OCIE0A); // Interrupt enabled but no sei()
}

/* Right: Enable global interrupts */
void timer_interrupt_enable_right() {
    TIMSK0 = (1 << OCIE0A);
    sei(); // Must call this to enable interrupts globally
}
📊

Quick Reference

Timer Interrupt Setup Steps:

  • Set timer mode (e.g., CTC) in control registers.
  • Choose prescaler to scale clock speed.
  • Load compare register with count value.
  • Enable timer interrupt in interrupt mask register.
  • Enable global interrupts with sei().
  • Write ISR with correct vector name.

Key Takeaways

Always enable global interrupts with sei() after enabling timer interrupts.
Set the timer mode and prescaler correctly to get accurate timing.
Define the ISR with the exact interrupt vector name for your timer.
Use volatile variables if shared between ISR and main code to avoid optimization issues.
Test timer interrupts with simple actions like toggling an LED to verify setup.