Mastering Timer and Counter Operations for Embedded Systems
Input capture, output compare, frequency measurement, and timing applications
- Overview
- Quick Reference: Key Facts
- Visual Understanding
- Conceptual Foundation
- Core Concepts
- Practical Considerations
- Additional Resources
Timers and counters are essential peripherals in embedded systems for precise timing, frequency measurement, PWM generation, and event counting. Understanding timer programming is crucial for real-time applications.
- Timer Modes: Up-counting, down-counting, center-aligned
- Input Capture: Edge detection, frequency measurement, pulse width measurement
- Output Compare: PWM generation, timing control, waveform generation
- Prescaler: Divides clock frequency to achieve desired timing resolution
- Auto-reload: Automatically reloads counter value for continuous operation
- Interrupts: Timer interrupts for precise timing events
- DMA Integration: High-speed data transfer without CPU intervention
- Can you compute timer frequency/period from clock and prescaler?
- Do you understand capture vs compare use cases?
- Can you reason about jitter, ISR cost, and DMA trade‑offs?
Clock Source → Prescaler → Counter → Compare/Output → Interrupt/DMA
↓ ↓ ↓ ↓ ↓
System Clock Divide by Count Up/ Generate Trigger
(84 MHz) PSC+1 Down/ PWM/Events CPU Events
Center
Up-Counting: 0 → 1 → 2 → ... → ARR → 0 → 1 → ...
Down-Counting: ARR → ARR-1 → ... → 1 → 0 → ARR → ...
Center-Aligned: 0 → 1 → ... → ARR → ARR-1 → ... → 1 → 0 → ...
Input Capture: External Event → Capture Timer Value → Calculate Timing
↓ ↓ ↓
GPIO Edge Store Count Frequency/Pulse
in Register Width
Output Compare: Timer Count → Compare with CCR → Generate Output Event
↓ ↓ ↓
Increment Match Value PWM/Interrupt
Counter (CCR Register) Generation
Timers serve as the fundamental building blocks for all time-related operations in embedded systems. They provide:
- Precise Timing: Hardware-based timing with minimal jitter
- Event Scheduling: Predictable execution of periodic tasks
- Measurement Capability: Accurate frequency and time interval measurement
- Waveform Generation: Creation of precise timing patterns and PWM signals
Timer programming is critical because:
- Real-Time Requirements: Many embedded applications require precise timing
- System Synchronization: Coordinating multiple system events and peripherals
- Power Efficiency: Timers enable sleep modes and wake-up timing
- Performance Optimization: Hardware timers offload timing tasks from the CPU
Designing timer systems involves balancing several competing concerns:
- Resolution vs. Range: Higher resolution (smaller prescaler) reduces maximum period
- Accuracy vs. Complexity: More precise timing requires careful configuration
- Hardware vs. Software: Hardware timers vs. software timing loops
- Interrupt Frequency: Balancing timing precision with system overhead
Why it matters: Proper timer configuration ensures accurate timing and prevents overflow errors. Understanding the relationship between clock frequency, prescaler, and period is essential for achieving desired timing resolution and range.
Minimal example
// Basic timer configuration structure
typedef struct {
uint32_t prescaler; // Timer prescaler value
uint32_t period; // Timer period (ARR value)
uint32_t clock_freq; // Timer clock frequency
uint32_t mode; // Timer mode (UP, DOWN, CENTER)
} timer_config_t;
// Calculate timer frequency
uint32_t calculate_timer_frequency(uint32_t clock_freq, uint32_t prescaler, uint32_t period) {
return clock_freq / ((prescaler + 1) * (period + 1));
}
// Calculate timer period for target frequency
uint32_t calculate_timer_period(uint32_t clock_freq, uint32_t prescaler, uint32_t target_freq) {
return (clock_freq / ((prescaler + 1) * target_freq)) - 1;
}Try it: Calculate the prescaler and period values needed for a 1kHz timer using an 84MHz clock.
Takeaways
- Prescaler divides the input clock frequency
- Period determines the timer overflow frequency
- Higher prescaler values provide longer timing periods
- Always verify calculations to prevent overflow
Why it matters: Input capture enables precise measurement of external events, making it essential for frequency measurement, pulse width analysis, and event timing in embedded systems.
Minimal example
// Input capture configuration
typedef struct {
uint32_t channel; // Timer channel (1-4)
uint32_t edge; // Rising/Falling edge
uint32_t filter; // Input filter value
bool interrupt_enable; // Enable capture interrupt
} input_capture_config_t;
// Configure input capture
void configure_input_capture(TIM_HandleTypeDef* htim, input_capture_config_t* config) {
// Configure channel as input
TIM_IC_InitTypeDef sConfigIC = {0};
sConfigIC.ICPolarity = config->edge;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = config->filter;
HAL_TIM_IC_ConfigChannel(htim, &sConfigIC, config->channel);
// Enable interrupt if requested
if (config->interrupt_enable) {
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1 << (config->channel - 1));
}
}Try it: Implement input capture to measure the frequency of an external signal.
Takeaways
- Input capture stores timer value when external event occurs
- Edge selection affects measurement accuracy
- Input filtering reduces noise sensitivity
- Interrupts enable real-time event processing
Why it matters: Output compare enables precise generation of timing events, PWM signals, and periodic outputs. It's fundamental for motor control, audio generation, and timing synchronization.
Minimal example
// Output compare configuration
typedef struct {
uint32_t channel; // Timer channel (1-4)
uint32_t compare_value; // Compare value (CCR)
uint32_t mode; // Output mode (Toggle, PWM, Force)
bool interrupt_enable; // Enable compare interrupt
} output_compare_config_t;
// Configure output compare
void configure_output_compare(TIM_HandleTypeDef* htim, output_compare_config_t* config) {
// Configure channel as output
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = config->mode;
sConfigOC.Pulse = config->compare_value;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(htim, &sConfigOC, config->channel);
// Enable interrupt if requested
if (config->interrupt_enable) {
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1 << (config->channel - 1));
}
}Try it: Generate a 1kHz square wave with 50% duty cycle using output compare.
Takeaways
- Output compare generates events when timer matches compare value
- Compare value determines timing of output events
- Multiple channels enable complex timing patterns
- Interrupts provide precise event notification
Why it matters: Timer interrupts and DMA integration enable efficient handling of timing events and high-speed data transfer, reducing CPU overhead and improving system performance.
Minimal example
// Timer interrupt configuration
void configure_timer_interrupt(TIM_HandleTypeDef* htim, uint32_t priority) {
// Enable timer update interrupt
__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
// Configure NVIC priority
HAL_NVIC_SetPriority(TIM2_IRQn, priority, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
// Timer interrupt handler
void TIM2_IRQHandler(void) {
if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET) {
if (__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) != RESET) {
__HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);
// Handle timer event
handle_timer_event();
}
}
}Try it: Implement a timer interrupt that toggles an LED every 500ms.
Takeaways
- Timer interrupts provide precise timing for event handling
- Keep interrupt handlers short and efficient
- Use DMA for high-speed data transfer
- Proper priority configuration prevents timing conflicts
Objective: Configure a timer to generate periodic interrupts and measure timing accuracy.
Steps:
- Configure a timer for 1kHz operation
- Enable timer interrupts
- Toggle GPIO pin in interrupt handler
- Measure timing accuracy with oscilloscope
Expected Outcome: Understanding of timer configuration and interrupt timing.
Objective: Use input capture to measure the frequency of an external signal.
Steps:
- Configure timer channel for input capture
- Generate test signal with function generator
- Implement frequency calculation algorithm
- Compare measured vs. actual frequency
Expected Outcome: Practical experience with input capture and frequency measurement.
Objective: Generate PWM signals with variable duty cycle using output compare.
Steps:
- Configure timer for PWM mode
- Implement duty cycle control
- Generate different PWM frequencies
- Measure PWM characteristics with oscilloscope
Expected Outcome: Understanding of PWM generation and output compare operation.
- What is the difference between timer and counter modes?
- How do you calculate timer frequency from clock, prescaler, and period?
- What are the main applications of input capture and output compare?
- How would you configure a timer for 100Hz operation with 1ms resolution?
- What considerations are important when choosing timer prescaler values?
- How do you implement precise timing measurement using timers?
- How do you handle timer overflow in long-duration measurements?
- What are the trade-offs between hardware and software timing?
- How do you synchronize multiple timers for complex applications?
- GPIO Configuration - GPIO modes, configuration, electrical characteristics
- Pulse Width Modulation - PWM generation, frequency control, duty cycle
- External Interrupts - Edge/level triggered interrupts, debouncing
- Interrupts and Exceptions - Interrupt handling and ISR design
- Hardware Abstraction Layer - Timer abstraction and portability
- Timer Selection: Choose appropriate timer based on resolution and range requirements
- Interrupt Frequency: Balance timing precision with system overhead
- Resource Allocation: Consider timer sharing between multiple applications
- Prescaler Selection: Optimize for desired timing resolution and range
- Interrupt Efficiency: Minimize ISR execution time
- DMA Usage: Use DMA for high-speed timer applications
- Timing Verification: Use oscilloscope or logic analyzer to verify timing
- Interrupt Debugging: Monitor interrupt timing and frequency
- Performance Profiling: Measure timer accuracy and jitter
- STM32CubeMX - Timer configuration
- Timer Calculator
- "Embedded Systems: Introduction to ARM Cortex-M Microcontrollers" by Jonathan Valvano
- "Making Embedded Systems" by Elecia White
Next Topic: Watchdog Timers → Interrupts and Exceptions