[ Curiosity,Experimentation ]

Random stuff from the parallel universe of Ones and Zeroes

Programming the Timers in AVR [avr-gcc]

Posted by appusajeev on July 16, 2010

All the Atmel® AVR microcontrollers have TIMERs as an inbuilt peripheral . They can be used to generate PWM(Pulse Width Modulation)waves, for generating accurately timed pulses and for registering the timestamp of external events(Input capture mode). ATMEGA 16 and ATMEGA 8(which we focus on in this post) microcontrollers have 3 inbuilt timers in them, one 16 bit timer and two 8 bit timers. These timers run independent of the program being executed and are capable of generating interrupts. Here i will be explaining about the 16 bit timer 1 of ATMEGA 8 and the same applies to ATMEGA 16 as well.

A timer (also called as counter) is simply a device that counts upon receiving clock pulses. The timer increments (or decrements in certain cases)its count with each clock tick it receives.  A timer is usually specified by the maximum value to which it can count (called MAX) beyond which it overflows and resets to zero(BOTTOM). Thus an 8-bit timer/counter can count from 0 through 255 and a 16-bit timer/counter can count from 0 through 65,535.
The speed of counting can be controlled by varying the speed of clock input to it. This is done by prescaling the clock of the microcontroller. By prescaling, we feed a fraction of the CPU clock to the timer.

Timer speed =F_CPU / prescaler

where F_CPU is the AVR CPU clock speed.Normal prescaler values are 1,8,64,256 and 1024. For example, for a 1MHZ clock, if prescaler is 64, then timer speed is  1000000/64=15625 i.e.  in one second,  the timer can count from 0 to 15625.
When the timer reaches the maximum value it can count, it is said to overflow and it automatically resets to 0 and starts counting again. We can set an interrupt to occur when the timer overflows.
When the timer 1 overflows, TOV1 bit will be set in the TIFR (Timer Interrupt Flag Register) register which will be cleared automatically when the corresponding ISR executes or it can be cleared by setting TOV1 bit to 1(odd, but that’s how ATMEL guys want us to clear it !).

Starting the timer

A counter starts counting as soon as it is set to use a clock source, by setting a suitable prescaler value bits CS10,CS11 and CS12 in the TCCR1B (Timer Counter Control Register 1 B )register . The instantaneous value of the timer is available anytime in the TCNT (Timer Count) register. Refer datasheet for more information on various bits in the register.

Timer in Compare Mode (CTC mode)

The timer used in above mode is of not much use as such. The AVR timer can be operated in a mode called CTC mode or Clear on Timer Capture mode in which we can set the timer to compare its count with a certain value set in OCR1A (Output Compare Register 1 A) register or OCR1B register and generate an interrupt or manipulate the OC1A or OC1B pin whenever a match occurs (i.e. when TCNT=OCR1A or TCNT=OCR1B).CTC mode can be used to generate accurate timings and square waves of desired frequency.
CTC mode can be enabled by setting WGM 12 bit=1 in TCCR1B register.
When TCNT=OCR1A, the timer resets and starts from 0 again. The value of OCR1A can be changed anytime and the change in the output will be reflected immediately.

toggling OC1A pin in CTC mode

toggling OC1A pin in CTC mode

When a match occurs we can either Set,Clear or toggle the OC1A/OC1B  pin.The action of OC1A pin can be set by setting suitable values for COM1A0 and COM1A1 bits in TCCR1A (Timer Counter Control Register 1 A) register (refer datasheet).

Whenever a compare match occurs, the OCF1A bit will be set in the TIFR(Timer Interrupt Flag Register) which will automatically be cleared when the associated ISR fires or else we have to manually clear it by setting it to 1.

The following example demonstrates CTC mode of Timer 1. An LED is connected to t0 PB1 pin(pin 15) of Atmega8 which flashes at 1 hz.

Atmega8 Timer 1 in CTC toggle mode

Atmega8 Timer 1 in CTC toggle mode

Generating Square Waves

With the OC1A pin set to toggle by setting COM1A0=1 in TCCR1A register, this mode can be used to generate a square wave of required frequency(50% duty cycle only though) by setting a suitable value in the OCR1A register.
As said above, the value of OCR1A can be changed anytime and the change in the output will be reflected immediately

The frequency of the square wave generated is given by

f = F_CPU / (2.prescaler.(1+OCR1A))

Generating Square waves in CTC mode

Generating Square waves in CTC mode

For eg, to generate a 50Hz square wave, set OCR1A=291

Timers and interrupts

AVR timers can generate 3 types of interrupts- Overflow, Compare match and Input Capture (Input capture is a mode in which we can have the value of the  TCNT register copied to the ICR register whenever  a rising/falling edge is found on the ICP1 pin of the ATMEGA) and we can execute a user specified ISR for these as demonstrated.
To enable interrupts, first we have to enable compare match interrupt for  timer 1 by setting OCIE1A (Output Compare A Match Interrupt Enable) bit in the TIMSK register and then we have to enable global interrupts with the sei() macro. For handling overflow interrupts, set TOIE1 bit in TIMSK register to 1.

The following example demonstrates the use of interrupts. The interrupt service routine(ISR) toggles the LED connected to pin 1 of port B.

Timer 1 Interrupt Handling

Timer 1 Interrupt Handling


14 Responses to “Programming the Timers in AVR [avr-gcc]”

  1. vidya said

    hey..dear well done my boy :)!!!
    god bless u..<3 🙂

  2. […] Programming a Timers in AVR [avr-gcc] « [ Curiosity,Expermentation ] […]

  3. […] Programming the Timers in AVR [avr-gcc] […]

  4. Sandeep said

    nice work..Thanks.

  5. hey…nice work..but it would hav been much better if u wud hav not used bitwise operators as it makes program difficult to understand!!!

    • appusajeev said

      Thanks. Bitwise operators are the basic things to learn in embedded programming. And it makes program much more readable as opposed to your notion because, it shows which all bits in a registers are set by having a casual look at the program. It definitely makes more sense to do something like REG = (1<<BIT_NAME) instead of setting a value lie REG = 0x5C.

  6. Eeshaanee said


  7. Eeshaanee said

    Very Nice tutorial by the way, Very helpful..

  8. cuisinart dcc-1200…

    […]Programming the Timers in AVR [avr-gcc] « [ Curiosity,Expermentation ][…]…

  9. Sumanta Kumar Show said

    Myself Sumanta Kumar Show from IIT Kharagpur, Mining Dept. is forwarding the logic which we want to implement in the micro-controller. It is as follows –

    Suppose I have two ports name PORT1 and PORT2. Now the ports status will change by the following way:-

    5 V or Logic1 5 V or Logic1 Initial condition
    0 V or Logic0 5 V or Logic1 Timer Start
    0 V or Logic0 0 V or Logic0 Timer Stop

    Now the time gap between timer start and timer stop will be in nano-second range. I want to display this time delay on a display device. This

    will be done one time. It will not be done in a continuous manner. If need another experiment will perform manually by pressing power on/off

    switch or pressing reset button. Please send me your valuable suggestion (any device that makes it easy to attain the objective) at the


    • appusajeev said

      Hello Sumanta,

      I have experience with AVR microcontrollers only. You objective can be achieved through programming the timers and the time can be displayed on LCD too, but your nano-second timing requirement unfortunately cannot be met using the microcontrollers i know, as the ones i work with work in microseconds range. I am sorry i cannot be of much help in this situation.

      • Sumanta Kumar Show said

        Hello Appusajeev,

        Can you tell me the format of writing the program to have the timer operation in nanoseconds in AVR studio4? Is there any

        procedure that measurement in nanoseconds can be achieved through a hardware circuit comprising of the Logic Gates and other

        electronic components.

      • Sumanta Kumar Show said

        It would be better if you please inform me in Email Id – (sumanta.show@gmail.com / show.sumanta@rediffmail.com). Thanks in advance.

  10. abhishek said

    sir , i have a project to measure rpm of a wheel by hall effect sensor using atmega16.
    for that i need to use timers. can u please tell me a code to run timers for say 1 minute
    to get rpm(rotations per minute)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: