0
0
Power-electronicsHow-ToBeginner · 4 min read

Measure Pulse Width Using Timer in Embedded C: Simple Guide

To measure pulse width using a timer in Embedded C, configure the timer to capture the time at the rising and falling edges of the pulse signal. Calculate the difference between these two captured timer values to get the pulse width in timer ticks, then convert it to time units using the timer clock frequency.
📐

Syntax

To measure pulse width, you typically use input capture mode of a hardware timer. The key steps are:

  • Configure timer for input capture on the signal pin.
  • Capture timer value at rising edge (start of pulse).
  • Capture timer value at falling edge (end of pulse).
  • Calculate pulse width by subtracting the two captured values.

Basic syntax pattern in Embedded C:

c
void Timer_Init(void);
uint32_t Capture_RisingEdge(void);
uint32_t Capture_FallingEdge(void);

uint32_t pulse_width_ticks = 0;

void measure_pulse_width() {
    uint32_t start = Capture_RisingEdge();
    uint32_t end = Capture_FallingEdge();
    pulse_width_ticks = end - start;
}
💻

Example

This example shows how to measure pulse width on a microcontroller timer using input capture interrupts. It assumes a 1 MHz timer clock (1 tick = 1 microsecond).

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

volatile uint32_t rising_edge = 0;
volatile uint32_t falling_edge = 0;
volatile uint8_t capture_done = 0;

// Simulated timer register
volatile uint32_t TIMER_CNT = 0;

// Simulated input capture interrupt handler
void TIM_IC_IRQHandler(int edge) {
    if(edge == 1) { // Rising edge
        rising_edge = TIMER_CNT;
    } else { // Falling edge
        falling_edge = TIMER_CNT;
        capture_done = 1;
    }
}

int main() {
    // Simulate timer counting
    for(TIMER_CNT = 0; TIMER_CNT < 100000; TIMER_CNT++) {
        if(TIMER_CNT == 1000) TIM_IC_IRQHandler(1); // Rising edge at 1000 us
        if(TIMER_CNT == 3500) TIM_IC_IRQHandler(0); // Falling edge at 3500 us
        if(capture_done) break;
    }

    uint32_t pulse_width = falling_edge - rising_edge; // in microseconds
    printf("Pulse width: %lu microseconds\n", pulse_width);
    return 0;
}
Output
Pulse width: 2500 microseconds
⚠️

Common Pitfalls

  • Timer overflow: If the pulse is longer than the timer max count, the subtraction may be wrong. Handle overflow by checking if end < start and adding timer max count.
  • Incorrect edge detection: Make sure to capture rising and falling edges correctly; mixing them up gives wrong pulse width.
  • Timer clock frequency: Use the correct timer clock to convert ticks to real time units.
  • Interrupt latency: Avoid heavy processing in capture interrupts to prevent timing errors.
c
/* Wrong way: ignoring timer overflow */
uint32_t pulse_width_wrong(uint32_t start, uint32_t end) {
    return end - start; // fails if end < start due to overflow
}

/* Right way: handle overflow */
uint32_t pulse_width_correct(uint32_t start, uint32_t end, uint32_t timer_max) {
    if(end >= start) {
        return end - start;
    } else {
        return (timer_max - start) + end + 1;
    }
}
📊

Quick Reference

Tips for measuring pulse width with timer:

  • Use input capture mode for precise edge timing.
  • Record timer count at rising and falling edges.
  • Subtract counts to get pulse width in ticks.
  • Convert ticks to time using timer frequency.
  • Handle timer overflow carefully.

Key Takeaways

Configure timer input capture to record rising and falling edges of the pulse.
Calculate pulse width by subtracting captured timer values and handle timer overflow.
Convert timer ticks to real time using the timer clock frequency.
Ensure correct edge detection and minimal interrupt processing for accuracy.
Test with known pulse signals to verify measurement correctness.