0
0
Power-electronicsHow-ToBeginner · 3 min read

How to Create Periodic Task Using Timer in Embedded C

To create a periodic task in embedded C, configure a hardware timer to generate interrupts at fixed intervals and write the task code inside the timer interrupt service routine (ISR). This setup ensures the task runs automatically and repeatedly without blocking the main program.
📐

Syntax

Setting up a periodic task with a timer involves these steps:

  • Initialize the timer with a specific period.
  • Enable timer interrupts.
  • Write the interrupt service routine (ISR) to execute the periodic task.
  • Start the timer.

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

c
void Timer_Init(void) {
    // Configure timer registers for desired period
    TIMER_REG = TIMER_PERIOD_VALUE;
    // Enable timer interrupt
    TIMER_INTERRUPT_ENABLE = 1;
    // Start timer
    TIMER_START = 1;
}

void Timer_ISR(void) {
    // Clear interrupt flag
    TIMER_INTERRUPT_FLAG = 0;
    // Periodic task code here
}
💻

Example

This example shows how to toggle an LED every 1 second using a timer interrupt on a generic microcontroller.

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

volatile bool led_state = false;

// Mock hardware registers
volatile uint32_t TIMER_REG = 0;
volatile uint8_t TIMER_INTERRUPT_ENABLE = 0;
volatile uint8_t TIMER_INTERRUPT_FLAG = 0;
volatile uint8_t TIMER_START = 0;

#define TIMER_PERIOD_VALUE 1000 // Timer counts for 1 second

void Timer_Init(void) {
    TIMER_REG = TIMER_PERIOD_VALUE;
    TIMER_INTERRUPT_ENABLE = 1;
    TIMER_START = 1;
}

void Timer_ISR(void) {
    TIMER_INTERRUPT_FLAG = 0; // Clear interrupt flag
    led_state = !led_state;   // Toggle LED state
    if (led_state) {
        // Turn LED ON (simulate)
        printf("LED ON\n");
    } else {
        // Turn LED OFF (simulate)
        printf("LED OFF\n");
    }
}

int main(void) {
    Timer_Init();

    // Simulate timer interrupts every 1 second
    for (int i = 0; i < 5; i++) {
        // Simulate timer interrupt trigger
        TIMER_INTERRUPT_FLAG = 1;
        if (TIMER_INTERRUPT_FLAG && TIMER_INTERRUPT_ENABLE) {
            Timer_ISR();
        }
    }

    return 0;
}
Output
LED ON LED OFF LED ON LED OFF LED ON
⚠️

Common Pitfalls

  • Not clearing the interrupt flag: Forgetting to clear the timer interrupt flag inside the ISR causes repeated interrupts and can freeze the system.
  • Long ISR execution: Writing heavy code inside the ISR can delay other interrupts and affect system responsiveness.
  • Incorrect timer configuration: Setting wrong timer period or prescaler leads to incorrect timing intervals.
  • Not enabling global interrupts: The timer interrupt won't work if global interrupts are disabled.
c
/* Wrong: Missing interrupt flag clear */
void Timer_ISR(void) {
    // TIMER_INTERRUPT_FLAG = 0; // Missing clear
    // Task code
}

/* Correct: Clear interrupt flag */
void Timer_ISR(void) {
    TIMER_INTERRUPT_FLAG = 0; // Clear flag
    // Task code
}
📊

Quick Reference

Remember these key points when creating periodic tasks with timers:

  • Configure timer period and prescaler for desired interval.
  • Enable timer interrupts and global interrupts.
  • Write short, fast ISR code.
  • Always clear the interrupt flag inside ISR.
  • Start the timer to begin counting.

Key Takeaways

Configure hardware timer and enable its interrupt to create periodic tasks.
Write the periodic task code inside the timer interrupt service routine (ISR).
Always clear the timer interrupt flag inside the ISR to avoid repeated triggers.
Keep ISR code short to maintain system responsiveness.
Ensure global interrupts are enabled for timer interrupts to work.