Pages Menu
Categories Menu

Posted by on Jun 22, 2011 in Atmel AVR, Getting Started, Microcontrollers | 140 comments

Introduction to AVR Timers

Introduction to AVR Timers

TimersAVR Series

Timers are used everywhere. Without timers, you would end up nowhere! The range of timers vary from a few microseconds (like the ticks of a processor) to many hours (like the lecture classes :( ), and AVR is suitable for the whole range! AVR boasts of having a very accurate timer, accurate to the resolution of microseconds! This feature makes them suitable for timer applications. Let’s see how.

You come across timers everyday. Simplest example hangs on your wall or maybe tied around your wrist. You can say that they have a unique property to measure time. Everything in this world is synchronized with time. You wake up at, say, 6 o’clock; you work everyday for 8 hours; you need to drink water every 4 hours, etc. But the concept of timers isn’t confined to your daily routines. Every electronic component works on a time base. This time base helps to keep all the work synchronized. Without a time base, you would have no idea as to when to do a particular thing.

Thus, timers is an important concept in the field of electronics. You can generate a time base using a timer circuit, using a microcontroller, etc. Since all the microcontrollers work at some predefined clock frequency, they all have a provision to set up timers.

AVR boasts of having a timer which is very accurate, precise and reliable. It offers loads of features in it, thus making it a vast topic. In this tutorial, we will discuss the basic concepts of AVR Timers. We will not be dealing with any code in this tutorial, just the concepts. The procedure of generating timers and their codes will be discussed in subsequent posts.

Timers as registers

So basically, a timer is a register! But not a normal one. The value of this register increases/decreases automatically. In AVR, timers are of two types: 8-bit and 16-bit timers. In an 8-bit timer, the register used is 8-bit wide whereas in 16-bit timer, the register width is of 16 bits. This means that the 8-bit timer is capable of counting 2^8=256 steps from 0 to 255 as demonstrated below.

8 bit Counter

8 bit Counter

Similarly a 16 bit timer is capable of counting 2^16=65536 steps from 0 to 65535. Due to this feature, timers are also known as counters. Now what happens once they reach their MAX? Does the program stop executing? Well, the answer is quite simple. It returns to its initial value of zero. We say that the timer/counter overflows.

In ATMEGA32, we have three different kinds of timers:

The best part is that the timer is totally independent of the CPU. Thus, it runs parallel to the CPU and there is no CPU’s intervention, which makes the timer quite accurate.

Apart from normal operation, these three timers can be either operated in normal mode, CTC mode or PWM mode. We will discuss them one by one.

Timer Concepts

Basic Concepts

Since childhood, we have been coming across the following formula:

T = 1/fNow suppose, we need to flash an LED every 10 ms. This implies that its frequency is 1/10ms = 100 Hz. Now let’s assume that we have an external crystal XTAL of 4 MHz. Hence, the CPU clock frequency is 4 MHz. Now, as I said that the timer counts from 0 to TOP. For an 8-bit timer, it counts from 0 to 255 whereas for a 16-bit timer it counts from 0 to 65535. After that, they overflow. This value changes at  every clock pulse.

Let’s say the timer’s value is zero now. To go from 0 to 1, it takes one clock pulse. To go from 1 to 2, it takes another clock pulse. To go from 2 to 3, it takes one more clock pulse. And so on. For F_CPU = 4 MHz, time period T = 1/4M = 0.00025 ms. Thus for every transition (0 to 1, 1 to 2, etc), it takes only 0.00025 ms!

Now, as stated above, we need a delay of 10 ms. This maybe a very short delay, but for the microcontroller which has a resolution of 0.00025 ms, its quite a long delay! To get an idea of how long it takes, let’s calculate the timer count from the following formula:

Timer CountSubstitute Required Delay = 10 ms and Clock Time Period = 0.00025 ms, and you get Timer Count = 39999. Can you imagine that? The clock has already ticked 39999 times to give a delay of only 10 ms!

Now, to achieve this, we definitely cannot use an 8-bit timer (as it has an upper limit of 255, after which it overflows). Hence, we use a 16-bit timer (which is capable of counting up to 65535) to achieve this delay.

The Prescaler

Assuming F_CPU = 4 MHz and a 16-bit timer (MAX = 65535), and substituting in the above formula, we can get a maximum delay of 16.384 ms. Now what if we need a greater delay, say 20 ms? We are stuck?!

Well hopefully, there lies a solution to this. Suppose if we decrease the F_CPU from 4 MHz to 0.5 MHz (i.e. 500 kHz), then the clock time period increases to 1/500k = 0.002 ms. Now if we substitute Required Delay = 20 ms and Clock Time Period = 0.002 ms, we get Timer Count = 9999. As we can see, this can easily be achieved using a 16-bit timer. At this frequency, a maximum delay of 131.072 ms can be achieved.

Now, the question is how do we actually reduce the frequency? This technique of frequency division is called prescaling. We do not reduce the actual F_CPU. The actual F_CPU remains the same (at 4 MHz in this case). So basically, we derive a frequency from it to run the timer. Thus, while doing so, we divide the frequency and use it. There is a provision to do so in AVR by setting some bits which we will discuss later.

But don’t think that you can use prescaler freely. It comes at a cost. There is a trade-off between resolution and duration. As you must have seen above, the overall duration of measurement has increased from a mere 16.384 ms to 131.072 ms. So has the resolution. The resolution has also increased from 0.00025 ms to 0.002 ms (technically the resolution has actually decreased). This means each tick will take 0.002 ms. So, what’s the problem with this? The problem is that the accuracy has decreased. Earlier, you were able to measure duration like 0.1125 ms accurately (0.1125/0.00025 = 450), but now you cannot (0.1125/0.002 = 56.25). The new timer can measure 0.112 ms and then 0.114 ms. No other value in between.

Choosing Prescalers

Let’s take an example. We need a delay of 184 ms (I have chosen any random number). We have F_CPU = 4 MHz. The AVR offers us the following prescaler values to choose from: 8, 64, 256 and 1024. A prescaler of 8 means the effective clock frequency will be F_CPU/8. Now substituting each of these values into the above formula, we get different values of timer value. The results are summarized as below:

Choosing Prescaler

Choosing Prescaler

Now out of these four prescalers, 8 cannot be used as the timer value exceeds the limit of 65535. Also, since the timer always takes up integer values, we cannot choose 1024 as the timer count is a decimal digit. Hence, we see that prescaler values of 64 and 256 are feasible. But out of these two, we choose 64 as it provides us with greater resolution. We can choose 256 if we need the timer for a greater duration elsewhere.

Thus, we always choose prescaler which gives the counter value within the feasible limit (255 or 65535) and the counter value should always be an integer.

We will discuss how to implement it in later posts.


Well, this is not exclusively related to timers, but I thought of discussing it as it is used in a variety of places. Let me explain it using an analogy. Say now you are reading my post. It’s dinner time and your mom (only if you live with your mom ;)) calls you for dinner. What do you do (if she gets too creepy)? You save your work and attend to your mom’s call, then return and resume reading. This is an example of interrupt.

In most microcontrollers, there is something called interrupt. This interrupt can be fired whenever certain conditions are met. Now whenever an interrupt is fired, the AVR stops and saves its execution of the main routine,  attends to the interrupt call (by executing a special routine, called the Interrupt Service Routine, ISR) and once it is done with it, returns to the main routine and continues executing it.

For example, in the condition of counter overflow, we can set up a bit to fire an interrupt whenever an overflow occurs. Now, during execution of the program, whenever an overflow occurs, an interrupt is fired and the CPU attends to the corresponding ISR. Now it’s up to us what do we want to do inside the ISR. We can toggle the value of a pin, or increment a counter, etc etc.

If you didn’t get the concept of interrupts and ISR, behold for sometime till we discuss it how to implement it in hardware.

So folks, I guess this much is enough for you to get a hold of what timers are and the features of AVR Timers. From the next post, we will implement these concepts and learn how to code the AVR!

So grab the RSS feeds or subscribe to my blog to stay updated! And don’t forget to post your response down below!


  1. Hello Mayank, I need some clarification, in the Atmega168 datasheet, in the features section, under peripherals features, they talk of real time counter with separate oscillator, does this mean that with a separate oscillator, say 32kHz crystal, i can implement a real time clock feature with this contoroller? If true, give me an insight please.Thank you.

    • Hello Stmpagi,
      Yes, with a 32kHz crystal, you would be able to achieve RTC operation. Please read the conversations of arulsubramaniam and Dheer here. Thanks.

      • Thank you for the clarification.. you really rock

  2. i want to generate 20ms pwm using 8 bit timer…. so please tell me what can i do for that????

    • Read the rest of the timer tutorials and you’ll figure out yourself!

  3. Thank you for your work in explaining AVR timers. This is one of the best guides on the Internet.

  4. sir, i just wanted to ask that these tutorial and code of timer and counter are applicable for atmega16…???

    • What do you think?

  5. i want to generate 30 seconds time using timer for my robot to move from start place to end place. Plus i have to capture run time timer count , as soon as sensor detects the crack.

    please help me what can i do for that????


    • What can you do? Read through my website!

  6. this is the best site to describe timer in easy way.thanks

  7. you said , F_CPU/8. , doesnt it supposed to convert 8bit to desimal first??

    • I am sorry, I don’t understand your question. Could you please be more specific and throw some more details?

  8. thanks, good explanation

    • Thanks, you’re welcome!

  9. how do use a timer in c++ to allow a function to execute for x seconds

    • Hello Kasbesh,
      In which context are you running this program? Is this code executing in a Linux environment, or Windows, or bare-metal (like AVR, PIC, ARM, etc.)? Which compiler will you be using?

  10. you give lot of stuff………i really enjoyed but i guess one inportant thing is still missing: stepper motor control using avr

    • Thanks for the suggestion Fazal. We’ll add it to our list soon. :)

  11. Max,

    You’re doing great job :) I really like reading your timer tutorials amazing :)

    Well-done :) simple and pure language :)

    • Thanks Kalpesh! :)

  12. Thank you very much,you are a great person to do that work.
    i want to be professional in AVR ,could you advice me,please.
    Thank you very much.

    • Mohamed,
      I don’t know what you mean by being “professional” in AVR, but you can always get started here! Enjoy!

  13. This is really good and helpful Bhaiya. Glad to be reading your work. (Y)

    • Thanks a lot for the appreciation. Read on!

  14. Max, too good blogs are these!!! You explains it in very easy manner..!! I will always follow and prefer your blogs to learn AVR and other microcontrollers also. You rocks man.>!!!

    • Thanks Chirag :D

      Keep reading ;)

  15. Your blog is just awesome and you are a very good tutor as well hope you keep posting and teach us a lot …..:)

    • Thanks David :D

      Keep reading ;)

    • Thanks!
      Keep Reading :D

  16. hi.thank you for your useful and complete tutorial Master hope to keep on..

    • Thank you for the feedback.

      Keep Reading. Keep Sharing. :D

  17. Hey Max.
    I used to programme a lot in PHP when i was like 14. In 17 i stop doing such things. Now Im 23 and 3 weeks later i discovered that language C is soo similar to PHP and in like 2 weeks I learned quite a lot from AVR, i made a prototype of “Grower Buddy” on Atmega32 with USB, RS232, DS1307, LCD (pfc…i2c), BLUETOOTH and ETHERNET (enc28j60) and so on with Java client app on windows mac and android… My friends like it so much, and.. I just learned from english tutorials on the net. Yours site expecially. And your site, Max, was the best one, like in style of describing, like in pictures, diagrams and everything. Thnak you so much Master ;) You should be something like a university teacher man. There are tuns of people who understand things in the world, but there is so f*****g small amount of them, who CAN actually TEACH. Like the student gets it all, fast and RIGHT. AND… YOU ARE ONE OF THEM…

    • Thank you Kuba! Those were some amazing words. I’m glad that you got an opportunity to learn from maxEmbedded. :)
      Keep learning, keep sharing! :)

  18. Thanks a lot ,I really enjoyed your tutorial

  19. My friend suggested me to read your tutorial, and its very awesome, easy to understand. Thanks a lot :)

    • We’re glad you like it. :)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: