3.4) AVR Timer Programming: Basic SFR Registers used – Timer 0, 1 & 2

posted by Hamid Sayyed • November 12, 2025 0 Comments

In AVR microcontrollers, each timer module (Timer0, Timer1, and Timer2) has a set of dedicated Special Function Registers (SFRs) used to configure and control timer operations. These registers store important control bits, prescaler settings, compare match values, and interrupt flags. Understanding these registers is the first step before starting any practical programming of timers — whether for generating delays, PWM, or counting external events.

In this post, we’ll look at the basic SFRs used with Timer 0, Timer 1, and Timer 2 in AVR microcontrollers like ATmega16/32 or ATmega328. We will also understand their bit structure and purpose.

1. Timer 0 – 8-bit Timer/Counter

Timer0 is an 8-bit timer/counter, which means it can count from 0x00 to 0xFF (0–255). It is commonly used for short delays, periodic interrupts, and PWM generation.

Register NameFunction
TCNT0Timer/Counter Register – holds the current count value (8-bit).
TCCR0Timer/Counter Control Register – selects prescaler, mode, and clock source.
OCR0Output Compare Register – stores compare value for match operations.
TIMSKTimer Interrupt Mask Register – enables specific timer interrupts.
TIFRTimer Interrupt Flag Register – indicates interrupt events like overflow or compare match.

Important Bits in TCCR0

Bit 7 – FOC0 : Force Output Compare (for non-PWM mode)
Bit 6 – WGM00 : Waveform Generation Mode bit 0
Bit 3 – WGM01 : Waveform Generation Mode bit 1
Bit 2:0 – CS02:CS00 : Clock Select bits (choose prescaler)
Example: To start Timer0 with a prescaler of 64: TCCR0 = (1<<CS01) | (1<<CS00);

2. Timer 1 – 16-bit Timer/Counter

Timer1 is a powerful 16-bit timer, capable of handling larger count ranges (0–65535). It supports advanced features such as Input Capture, Output Compare (A & B), and PWM modes. Timer1 is ideal for generating precise time delays, frequency generation, and measuring input signal durations.

Register NameFunction
TCNT1H / TCNT1L16-bit Timer/Counter Register (High and Low byte).
TCCR1AControl Register A – controls output compare mode and waveform generation.
TCCR1BControl Register B – selects clock source, input capture, and prescaler.
OCR1A / OCR1BOutput Compare Registers – store compare values for match events.
ICR1Input Capture Register – captures timer value on external trigger edge.
TIMSKInterrupt Mask Register – enables Timer1 interrupts.
TIFRInterrupt Flag Register – shows interrupt status flags.

Key Bits in TCCR1B

Bit 6 – ICNC1 : Input Capture Noise Canceler
Bit 4 – ICES1 : Input Capture Edge Select
Bit 3 – WGM13 : Waveform Generation Mode
Bit 0–2 – CS12:CS10 : Clock Select bits (prescaler selection)
Example: Configure Timer1 in normal mode with prescaler 256: TCCR1B = (1<<CS12);

3. Timer 2 – 8-bit Timer/Counter (with Asynchronous Mode)

Timer2 is also an 8-bit timer but supports an additional feature: it can run asynchronously using an external 32.768 kHz crystal. This makes it suitable for real-time clock (RTC) applications.

Register NameFunction
TCNT2Timer/Counter Register (8-bit count value).
TCCR2Timer/Counter Control Register – sets prescaler, mode, and source.
OCR2Output Compare Register – stores compare match value.
ASSRAsynchronous Status Register – used when Timer2 runs with external crystal.
TIMSK / TIFRInterrupt Mask and Flag Registers.

Key Bits in TCCR2

Bit 7 – FOC2 : Force Output Compare
Bit 6 – WGM20 : Waveform Generation Mode bit 0
Bit 3 – WGM21 : Waveform Generation Mode bit 1
Bit 2:0 – CS22:CS20 : Clock Select (prescaler)
Example: To use Timer2 with external 32.768 kHz crystal: ASSR = (1<<AS2); This enables asynchronous operation independent of CPU clock.

4. Summary Table – All Timer Registers

Timer Type Important Registers Key Features
Timer0 8-bit TCNT0, TCCR0, OCR0, TIMSK, TIFR Basic delay, PWM, event counting
Timer1 16-bit TCNT1H/L, TCCR1A/B, OCR1A/B, ICR1, TIMSK Input capture, precise delay, dual PWM
Timer2 8-bit TCNT2, TCCR2, OCR2, ASSR, TIMSK Asynchronous mode for RTC

5. Example Code: Initializing All Timers

#include <avr/io.h>

int main(void)
{
    // Timer0: Normal mode, prescaler 64
    TCCR0 = (1<<CS01) | (1<<CS00);
    TCNT0 = 0;

    // Timer1: Normal mode, prescaler 256
    TCCR1B = (1<<CS12);
    TCNT1 = 0;

    // Timer2: Normal mode, prescaler 128
    TCCR2 = (1<<CS22) | (1<<CS20);
    TCNT2 = 0;

    while(1);
}
Tip: Always clear the timer register (TCNTx = 0) before starting a new count, and enable global interrupts (sei()) if you are using overflow or compare match interrupts.

Conclusion

The AVR’s timers are controlled by a small set of Special Function Registers (SFRs), each serving a unique purpose such as counting, comparing, or generating interrupts. Timer0 and Timer2 are 8-bit modules ideal for short timing operations, while Timer1 is a 16-bit module suited for precise timing and waveform generation. Having a clear understanding of these registers makes programming timers in C much easier and efficient. In the next article, we’ll move to “Timer Modes in AVR: Normal, CTC, and PWM” with examples and waveforms.

Comments

Post a Comment

Subscribe to Post Comments [Atom]