Sep-18th-2008

AVR Timers – An Introduction

Timers are standard features of almost every microcontroller. So it is very important to learn their use. Since an AVR microcontroller has very powerful and multifunctional timers, the topic of timer is somewhat “vast”. Moreover there are many different timers on chip. So this section on timers will be multipart. I will be giving basic introduction first.

What is a timer ?

A timer in simplest term is a register. Timers generally have a resolution of 8 or 16 Bits. So a 8 bit timer is 8Bits wide so capable of holding value withing 0-255. But this register has a magical property ! Its value increases/decreases automatically at a predefined rate (supplied by user). This is the timer clock. And this operation does not need CPU’s intervention.
avr timers operation

Fig.: Basic Operation Of a Timer.

Since Timer works independently of CPU it can be used to measure time accurately. Timer upon certain conditions take some action automatically or inform CPU. One of the basic condition is the situation when timer OVERFLOWS i.e. its counted upto its maximum value (255 for 8 BIT timers) and rolled back to 0. In this situation timer can issue an interrupt and you must write an Interrupt Service Routine (ISR) to handle the event.

Fig.: Basic Operation Of a Timer.

Using The 8 BIT Timer (TIMER0)

The ATmega16 and ATmega32 has three different timers of which the simplest is TIMER0. Its resolution is 8 BIT i.e. it can count from 0 to 255. Note: Please read the “Internal Peripherals of AVRs” to have the basic knowledge of techniques used for using the OnChip peripherals(Like timer !) The Prescaler The Prescaler is a mechanism for generating clock for timer by the CPU clock. As you know that CPU has a clock source such as a external crystal of internal oscillator. Normally these have the frequency like 1 MHz,8 MHz, 12 MHz or 16MHz(MAX). The Prescaler is used to divide this clock frequency and produce a clock for TIMER. The Prescaler can be used to get the following clock for timer. No Clock (Timer Stop). No Prescaling (Clock = FCPU) FCPU/8 FCPU/64 FCPU/256 FCPU/1024 Timer can also be externally clocked but I am leaving it for now for simplicity.

TIMER0 Registers.

As you may be knowing from the article “Internal Peripherals of AVRs” every peripheral is connected with CPU from a set of registers used to communicate with it. The registers of TIMERs are given below.

TCCR0 – Timer Counter Control Register. This will be used to configure the timer.

tccr0 of atmega avr

Fig.: TCCR0 - Timer Counter Control Register 0

As you can see there are 8 Bits in this register each used for certain purpose. For this tutorial I will only focus on the last three bits CS02 CS01 CS00 They are the CLOCK SELECT bits. They are used to set up the Prescaler for timer.

TCNT0 – Timer Counter 0

 

 

Timer Interrup Mask Register TIMSK

 

This register is used to activate/deactivate interrupts related with timers. This register controls the interrupts of all the three timers. The last two bits (BIT 1 and BIT 0) Controls the interrupts of TIMER0. TIMER0 has two interrupts but in this article I will tell you only about one(second one for next tutorial). TOIE0 : This bit when set to “1” enables the OVERFLOW interrupt. Now time for some practical codes !!! We will set up timer to at a Prescaler of 1024 and our FCPU is 16MHz. We will increment a variable “count” at every interrupt(OVERFLOW) if count reaches 61 we will toggle PORTC0 which is connected to LED and reset “count= 0”. Clock input of TIMER0 = 16MHz/1024 = 15625 Hz Frequency of Overflow = 15625 /256 = 61.0352 Hz if we increment a variable “count” every Overflow when “count reach 61” approx one second has elapse.

Setting Up the TIMER0

  // Prescaler = FCPU/1024
   TCCR0|=(1<<CS02)|(1<<CS00);
 //Enable Overflow Interrupt Enable
   TIMSK|=(1<<TOIE0);
 //Initialize Counter
   TCNT0=0;
Now the timer is set and firing Overflow interrupts at 61.0352 Hz

The ISR

ISR(TIMER0_OVF_vect)
{
//This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
//CPU automatically call this when TIMER0 overflows.

//Increment our variable
   
   count++;
   if(count==61)
   {
   PORTC=~PORTC; //Invert the Value of PORTC
   count=0;
   }
}

Demo Program (AVR GCC)

Blink LED @ 0.5 Hz on PORTC[3,2,1,0]

#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t count;

void main()
{
   // Prescaler = FCPU/1024
   TCCR0|=(1<<CS02)|(1<<CS00);

   //Enable Overflow Interrupt Enable
   TIMSK|=(1<<TOIE0);

   //Initialize Counter
   TCNT0=0;

   //Initialize our varriable
   count=0;

   //Port C[3,2,1,0] as out put
   DDRC|=0x0F;

   //Enable Global Interrupts
   sei();

   //Infinite loop
   while(1);
}

ISR(TIMER0_OVF_vect)
{
   //This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
   //CPU automatically call this when TIMER0 overflows.

   //Increment our variable
   count++;
   if(count==61)
   {
      PORTC=~PORTC; //Invert the Value of PORTC
      count=0;
   }
}

Hardware

ATmega16 or ATmega32 running @ 16MHz. Connet LEDs using 330ohms resistors on PORTC[3,2,1,0]. If you are using xBoard you can connect four onboard LEDs to PORTC using four PIN Connectors. Thats it for now meet in next tutorial. And please don't forget to post a comment, I am waiting for them !

Download PDF version | Get Adobe Reader Free !!!


46 Responses to “AVR Timers – An Introduction”

  1. 1
    Timers in Compare Mode - Part I | eXtreme Electronics Says:

    [...] The compare feature is not present in the 8 bit TIMER0 of the ATmega8 so we will use the TIMER1 which is a 16 Bit timer. First we need to setup the timer’s prescaler as described in the Timer0 tutorial. Please see this tutorial for a basic introduction of TIMERs. [...]

  2. 2
    Van de Poel Dominic Says:

    can you send me a program to make a reaction tester please

  3. 3
    Avinash Says:

    @Van de Poel Dominic
    I don’t understand by “reaction tester” pls give details!

  4. 4
    PWM Signal Generation by Using AVR Timers. | eXtreme Electronics Says:

    [...] Introduction to AVR Timers [...]

  5. 5
    MtAVRest Says:

    When you write example code you should not use shortcuts. Shortcuts allow advanced programmers to code faster, but make it extremely difficult for beginning programmers to follow.

    Consider:

    x++; vs. x = x + 1;

    A beginner might not know what ++ does, and even if they do, x = x + 1 is still more clear and easier to follow.

    Now consider:

    TCCR0|=(1<<CS02)|(CS01);

    I know you are performing a bitwise operation on the timer counter control register. I know from your commenting the code that you are setting the prescaler to FCPU/1024. I know from the chart that means you are setting the last 3 bits to 1 0 1. Yet I have no idea what that line of code is doing. So if I wanted to set the clock prescaler to /512 I have no idea the change that would be needed.

    I’ve studied it and concluded that it appears this might do the same thing:

    // set prescaler to FCPU/1024 by setting last 3 bits of TCCR0 to 101
    TCCR0 = TCCR0 & 0b11111101 // turn off bit 1
    TCCR0 = TCCR0 | 0b00000101 // turn on bits 0 and 2

  6. 6
    Andrejs Cainikovs Says:

    MtAVRest, possible somewhere you’re right. But..

    1. Please agree that a real noob will not start it’s programmers career from firmware programming. Even if AVR’s are easiest.

    2. C++ is not Basic. I don’t see any reason to rewrite this code: x++. It is not obfuscated. It is syntax. And really simple one. Even more, there is a clear comment in the code:
    //Increment our variable
    count++;

    3. Now consider this:
    TCCR0|=(1<<CS02)|(CS01);
    And this:
    TCCR0 = TCCR0 & 0b11111101;
    TCCR0 = TCCR0 | 0b00000101;
    What are simpler to read? It is impossible to understand your code without looking at register documentation. First example, at least, have the register bit names.

    IMHO, author is good, but your comment is simply ignored.

    P.S. My blog is not such descriptive, but what the heck :) :
    http://blog.stranadurakov.com/2009/04/01/set-up-avr-timer-interrupt/

  7. 7
    Avinash Says:

    Hello Andrejs,
    :)

    Nice and Correct response to MtAVRest!

    I thank you for time and effort to answer his doubts precisely.

    Thank you again :)

  8. 8
    Pankaj Says:

    i couldn’t understand how have you obtained 0.5 Hz in the last code?

  9. 9
    Nischey Grover Says:

    @pankaj
    interrupts occur at around 61 Hz so in 1 sec there are 61 interrupts.therefore counter is set to 0 every 1 sec.that means portc is toggled every 1 sec.that means it is on for 1 sec and off for 1 sec.so time period is 2 sec and freq is 1/2=0.5Hz

  10. 10
    Avinash Says:

    @Nischey Grover

    Very Nice work to help out Pankaj. :)

  11. 11
    AVR Project - Digital Stop Watch with ATmega8 | eXtreme Electronics Says:

    [...] Using AVR Timers [...]

  12. 12
    Kalle Says:

    Hi, this is propably quite stupid question but i’ve been figuring it out several hours now with no luck.

    i’m getting this error: ‘TCCR0′ undeclared (first use in this function)

    So my compiler thinks TCCR0 is a variable that havent been introduced but it’s a register. right?

    how do i tell it to my compiler?

    I’m using AVR studio 4 as my compiler.

  13. 13
    Avinash Says:

    @Kalle,

    TCCR0 is a register associated with TIMER0. It will only be available in chips which has Timer 0. If you try to compile when a chip which does not has a specific peripheral (like TIMER0 in this case) you will get the above error. So please try to select appropriate chip like ATmega8 or ATmega16 from the configuration dialog of AVR Studio.

    AVR Studio usages is given here
    http://extremeelectronics.co.in/avr-tutorials/part-iv-the-hello-world-project/

  14. 14
    Andrejs Cainikovs Says:

    Kaile, first thing you need to tell us is what chip you are using, because there is some differences between some avr versions.
    For example, TCCR0 should be TCCR0A in ATmega164P/324P/644P.

  15. 15
    Kalle Says:

    It works now, had to rename TCCR0 to TCCR0A for my chip. Thanks for fast replies.

  16. 16
    Andrejs Cainikovs Says:

    No problem, glad this helped. ;)

  17. 17
    Aditya Sharma Says:

    Hi, i am not getting clear idea about this statement
    TCCR0|=(1<<CS02)|(CS01);
    I understood the logic that this command sets the TIMER0 to 00000101 by bitwise operation (for prescaler to be FCPU/1024), but how this is happening, please elaborate.

    I understood other two syntaxs-
    TCCR0 = TCCR0 & 0b11111101;
    TCCR0 = TCCR0 | 0b00000101;

  18. 18
    Aditya Sharma Says:

    volatile uint8_t count;

    ‘volatile’ I have not heard about this datatype, what this is for?

  19. 19
    Avinash Says:

    @Aditya Sharma

    Hey man see this
    http://extremeelectronics.co.in/avr-tutorials/programming-in-c-tips-for-embedded-development/

  20. 20
    Avinash Says:

    First of all volatile is NOT a data type. It is used to mark a varriable as volatile (what is this? Please read on).

    Suppose we write


    while(1)
    {
    if(a==250)
    {
    print("Done")
    break;
    }
    else
    {
    z++;
    }
    }

    When the compiler compiles the above code it tries to optimize the code. It sees that a is not modified any where in the loop, so instead of getting the value of ‘a’ from memory to register in each loop it just gets the value into register ONLY one time. It does same with all varriables which are not modified in the NORMAL course of loop execution. But what if the value of ‘a’ is modified by an ISR (interrupt service routine) !!! Interrupt can occur at any time thus breaking the normal course of execution and executing the ISR (which say increments ‘a’) and then silently continues execution from where it left.

    This kind of varriable that can be updated by Hardware are called volatile varriables. A very common example is PORT input PINs their value can be changed by the external environment (like presssing a button). Other varriables that are controlled 100 % by the software are simple varriables

    Got it ???

  21. 21
    Avinash Says:

    All varriable that are shared between ISR and main program MUST be “volatile”

  22. 22
    Aditya Sharma Says:

    Thanks for this really helpful explanation, the ‘volatile’ concept is clear to me now.

    Regarding bitwise operations i have understood the tutorial well before asking you the query. The problem was that earlier the statement was
    TCCR0|=(1<<CS02)|(CS01);
    and now you have changed it to..
    TCCR0|=(1<<CS02)|(1<<CS00);
    This one is of-course right, but the former one was wrong as i suppose so i pointed out.

    Thanks again;
    Aditya Sharma

  23. 23
    Aditya Sharma Says:

    Also, can you please answer the query posted by one of the user on this link…
    http://robozeal.blogspot.com/2009/03/basic-mechanisms.html
    he is having some doubts in Atmega8 programmer and some more stuff, i have not used Atmega8 and USB programmer so unable to clarify his doubt, Please do have a look if you don’t mine!

  24. 24
    Yuveer Says:

    which timer should i use to simulate a set of traffic lights? any idea on how i could implemnent in?

  25. 25
    Andrejs Cainikovs Says:

    Yuveer,

    Due to high delay you need to use 16-bit timer. You can use timer output from one side and 3 PIO outputs from other side to build simple traffic light matrix.
    In software, you just build interrupt which will analyze when and what to switch on or off depending on the global variables you set.

    Hope this will help.

  26. 26
    abcd Says:

    HI,
    i am new to this AVR controllers. If frequency of Overflow = 61.03Hz & when “count reach 61” approx one second has elapse.
    How did you calsulate one second elapse? Can’t it be 1ms?
    I dont understand this. Can you please help me?

  27. 27
    Avinash Says:

    @abcd

    Pls don’t flood with silly comments !!!!!!!!!!!!!!!!
    If you don’t know relation between time and frequency pls go for some other profession. :-(

  28. 28
    Andrejs Cainikovs Says:

    @abcd,

    Check Nischey Grover comment on this page dated June 18th, 2009 at 4:40 pm, it will explain you how this code is working.

  29. 29
    Avinash Says:

    I highly appreciate :) Mr Andrejs work of Finding and giving a solution to “abcd”.
    -Admin

  30. 30
    riyagiya Says:

    Hello Avinash,
    I read your AVR timer Introduction tutorial. For every 1 sec here timer 61 overflow interupts. Can you please explain me how to Initialize a timer to generate a overflow interrupt for every 15ms?

  31. 31
    Verda Fretz Says:

    Hi, what blog platform is this? Is it working for you or..? I would really like it if you could answer this question! Regards!

  32. 32
    Avinash Says:

    @Verda

    This is Wordpress !!!

  33. 33
    sunil das Says:

    i found it quite helpful for me ….it helped me clear my concepts and hope more n more such tutorials ..thanx a lot

  34. 34
    Jay Says:

    Frequency of Overflow = 15625 /256 = 61.0352 Hz
    Can some explain to me the logic behind dividing the Clockfrequency by 256.

  35. 35
    Avinash Says:

    @Jay

    Didn’t you read 2nd Paragraph? Timer Overflow?

    I get angry when I see questions like this.

    When you not get anything you should try to read again.

  36. 36
    Avinash Says:

    @Jay

    Why would anyone explain you the same thing that is written above?

    Can’t you get simple arithmetic ???

  37. 37
    Claudiu Says:

    @Jay
    same question throws in my head … but like Avinash said, you have to read again to understand.

    (Answer: because the TIMER0 is 8-bit wide so it can count 2^8=256 clocks, but only one time it generate an overflow in those 256 clocks)

    @Avinash
    Keep up the good work … you are amazing !!!

  38. 38
    Sayantan Says:

    I find your comments very helpful to me.Now I have a question
    if I need multiple time-delay of various times,what to do ?I mean there is just only one 16 bit timer-counter,how to use it for all that time-delay?Please help me.

  39. 39
    Andrejs Cainikovs Says:

    Sayantan,

    Depending on the chip there may be few timers that you could use (megaAVR has max 4 of them). If you need to get one more timer you probably have two options:
    1. Move to a chip with higher 16-bit timer count
    2. Try to optimize your code so it will share your timer with another code.

  40. 40
    Kieron Says:

    I have got some problem dealing with the timer0 and timer2 which are used to control the steps of two stepper motors on my robot. In order to use PID controller I will need the motors to change the speed according to the output of the controller. If I were to use the OCR0 and OCR2 (reducing/increasing) to change the speed of the motors, how would i know what is the speed the motors are going??for example i want the motors to move forward at 12.56cm/sec. I will have to enable the interrupt to increase the steps of the motors but how would i know what speed are they going at???

  41. 41
    Kieron Says:

    do u have any examples that i can look into for controlling two stepper motors at different speeds based on the situation it is in by using the interrupts. I have seen the examples of one stepper motor using timer0 but it was not very helpful because the steps of the motors are predefined and that is not the case in my project.

  42. 42
    time interrupt activated button avr « Msmihai's Blog Says:

    [...] Here is a pretty good tutorial on the 8 bit timer. [...]

  43. 43
    Servo Motor Control by Using AVR ATmega32 Microcontroller | eXtreme Electronics Says:

    [...] Introduction To AVR Timers [...]

  44. 44
    prabu Says:

    niece contents ……………….helpful 4 all beginners…niece approach with eg.

  45. 45
    prabu Says:

    avinash good work

  46. 46
    Abraham Says:

    Awesome tutorials….I have gone through most of them…and they are so simple and elegant….I will be forever grateful to you..:) Do keep up the good work.

Leave a Reply

Comments

    • Akhila: thank you sir.
    • kiran: Thank you Avinash..i didn’t read the user manual thats the problem ..any how thank you.....
    • Akhila: Sir, I’m working on my final yr proj which is based on “Swarmbots”.I would...
    • Uttam Dutta: RGB LED are expected from long before, now easily avilabe, thank you, may be breadboard...
    • Sayantan: sir,can u please upload the custom characters tutorial for a 16×2 lcd (4-wire)module.I have...
    • kiran: Good tutorial ..In last tutorial you created library for Progfx with extension of .lib file...
    • Abraham: Awesome tutorials….I have gone through most of them…and they are so simple and...

Video

  • Comments

    • Akhila: thank you sir.
    • kiran: Thank you Avinash..i didn’t read the user manual thats the problem ..any how thank you.....
    • Akhila: Sir, I’m working on my final yr proj which is based on “Swarmbots”.I would...
    • Uttam Dutta: RGB LED are expected from long before, now easily avilabe, thank you, may be breadboard...
    • Sayantan: sir,can u please upload the custom characters tutorial for a 16×2 lcd (4-wire)module.I have...
    • kiran: Good tutorial ..In last tutorial you created library for Progfx with extension of .lib file...
    • Abraham: Awesome tutorials….I have gone through most of them…and they are so simple and...