0
0
Power-electronicsHow-ToBeginner · 4 min read

How to Implement Software Timer in Embedded C Easily

To implement a software timer in embedded C, use a hardware timer interrupt to increment a counter variable periodically. Check this counter in your main program to trigger actions after a set time interval.
📐

Syntax

A software timer typically uses a volatile counter variable updated inside a hardware timer interrupt service routine (ISR). The main program checks this counter to perform timed actions.

Key parts:

  • volatile uint32_t timer_counter; - counter updated by ISR
  • ISR() - interrupt routine increments the counter
  • if (timer_counter >= target) - check if timer expired
c
volatile uint32_t timer_counter = 0;

// Timer interrupt service routine
void Timer_ISR(void) {
    timer_counter++;
}

// Main loop
int main(void) {
    while(1) {
        if (timer_counter >= TARGET_VALUE) {
            // Timer expired, do something
            timer_counter = 0; // reset timer
        }
    }
}
💻

Example

This example shows a software timer that toggles an LED every 1 second using a hardware timer interrupt that fires every 10 ms.

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

volatile uint32_t timer_counter = 0;

// Simulated hardware register for LED (1 = ON, 0 = OFF)
uint8_t LED = 0;

// Simulated Timer ISR called every 10 ms
void Timer_ISR(void) {
    timer_counter++;
}

void delay_ms(int ms) {
    for (int i = 0; i < ms; i++) {
        Timer_ISR(); // simulate timer interrupt
    }
}

int main(void) {
    while (1) {
        delay_ms(10); // simulate 10 ms timer tick

        if (timer_counter >= 100) { // 100 * 10ms = 1 second
            LED = !LED; // toggle LED
            timer_counter = 0; // reset timer
            if (LED) {
                // LED ON
                // In real embedded, set GPIO high
                // Here we print
                printf("LED ON\n");
            } else {
                // LED OFF
                printf("LED OFF\n");
            }
        }
    }
    return 0;
}
Output
LED ON LED OFF LED ON LED OFF LED ON LED OFF
⚠️

Common Pitfalls

Common mistakes when implementing software timers include:

  • Not declaring the timer counter as volatile, causing compiler optimizations to break timing.
  • Updating the timer counter outside the interrupt, leading to inaccurate timing.
  • Not resetting the timer counter after the timer expires, causing repeated triggers.
  • Using blocking delays instead of interrupts, which freezes the program.
c
/* Wrong: timer_counter not volatile, may cause wrong behavior */
uint32_t timer_counter = 0;

void Timer_ISR(void) {
    timer_counter++;
}

/* Right: declare as volatile to prevent optimization issues */
volatile uint32_t timer_counter = 0;

void Timer_ISR(void) {
    timer_counter++;
}
📊

Quick Reference

Tips for software timers in embedded C:

  • Use hardware timer interrupts for accurate timing.
  • Declare timer counters as volatile.
  • Keep ISR code short and fast.
  • Reset counters after timer events.
  • Avoid blocking delays; use timers instead.

Key Takeaways

Use a hardware timer interrupt to increment a volatile counter for software timing.
Check the counter in your main loop to trigger timed actions and reset it afterward.
Always declare timer counters as volatile to avoid compiler optimization issues.
Keep interrupt service routines short to maintain system responsiveness.
Avoid blocking delays; rely on software timers for non-blocking timing.