How to Configure Timer Mode in Embedded C: Simple Guide
To configure timer mode in embedded C, set the timer control registers to select the desired mode (e.g., normal, CTC, PWM) and configure the prescaler for timer speed. Use
TCCRn registers to set mode bits and TCNTn to initialize the timer count.Syntax
Timer configuration involves setting control registers and prescalers. For example, in AVR microcontrollers, TCCRn controls timer mode, TCNTn sets the timer count, and TIMSK enables interrupts.
- TCCRn: Timer/Counter Control Register to select mode and clock source.
- TCNTn: Timer/Counter Register to set initial count value.
- TIMSK: Timer Interrupt Mask Register to enable timer interrupts.
c
/* Example syntax for setting Timer1 to CTC mode with prescaler 64 */ TCCR1A = 0x00; // Normal port operation, OC1A/OC1B disconnected TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC mode, prescaler 64 TCNT1 = 0; // Initialize counter OCR1A = 25000; // Compare value for 1 second delay (assuming 16MHz clock) TIMSK1 = (1 << OCIE1A); // Enable Timer1 compare interrupt
Example
This example configures Timer1 in CTC mode on an AVR microcontroller to toggle an LED every second using interrupts.
c
#include <avr/io.h> #include <avr/interrupt.h> void timer1_init() { TCCR1A = 0x00; // Normal port operation TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC mode, prescaler 64 OCR1A = 25000; // Compare value for 1 second delay TCNT1 = 0; // Reset timer count TIMSK1 = (1 << OCIE1A); // Enable Timer1 compare interrupt sei(); // Enable global interrupts } ISR(TIMER1_COMPA_vect) { PORTB ^= (1 << PORTB5); // Toggle LED on pin PB5 } int main(void) { DDRB |= (1 << DDB5); // Set PB5 as output timer1_init(); while(1) { // Main loop does nothing, LED toggled by interrupt } return 0; }
Output
LED connected to PB5 toggles ON and OFF every 1 second
Common Pitfalls
- Not setting the correct bits in
TCCRnfor the desired timer mode causes unexpected behavior. - Forgetting to enable global interrupts with
sei()means interrupt service routines won't run. - Incorrect prescaler values lead to wrong timer speeds and delays.
- Not initializing
TCNTncan cause timer to start from an unknown count.
c
/* Wrong: Missing prescaler bits, timer won't start */ TCCR1B = (1 << WGM12); // CTC mode but no clock source set /* Right: Include prescaler bits to start timer */ TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC mode, prescaler 64
Quick Reference
| Register/Bit | Purpose | Example Value |
|---|---|---|
| TCCRn | Select timer mode and clock prescaler | TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10) |
| TCNTn | Timer counter initial value | TCNT1 = 0 |
| OCRnA | Output compare register for CTC mode | OCR1A = 25000 |
| TIMSK | Enable timer interrupts | TIMSK1 = (1 << OCIE1A) |
| sei() | Enable global interrupts | sei() |
Key Takeaways
Set timer control registers (TCCRn) to select mode and prescaler correctly.
Initialize timer count (TCNTn) before starting the timer.
Enable interrupts and global interrupts if using timer interrupts.
Check prescaler values to get accurate timing delays.
Always verify timer mode bits to avoid unexpected behavior.