Posted by on Jun 29, 2011 in Atmel AVR, Microcontrollers | 43 comments

# AVR Timers – TIMER2

Hello friends! Welcome to the tutorial on the TIMER2 of AVR ATMEGA16/32. I hope that you have already come across and read the following posts, in which the basic concepts and applications of AVR Timers are discussed.

In this post, we will discuss about TIMER2. Since TIMER2 is an 8-bit timer (like TIMER0), most of the registers are similar to that of TIMER0 registers. Apart from that, TIMER2 offers a special feature which other timers don’t – Asynchronous Operation. We will discuss about it later.

Since you are already aware of the concepts (I assume so, or else refer to my previous posts), we will proceed the way we did in TIMER1 tutorial. We will implement both prescalers and interrupts in the same problem statement.

# Problem Statement

We need to flash an LED every 50 ms. We have an XTAL of 16 MHz. This is the same problem statement that we discussed in TIMER0 (the last one). We will implement the same using TIMER2.

### Methodology – Using Prescaler and Interrupt

As discussed in the TIMER0 tutorial, we use a prescaler of 256. For this, the overflow time is 4.096 ms. Thus the timer should overflow 12 times (MAX = 255) and count up to 53 in the 13th iteration, and then reset the timer. The formula used is as follows:Now let’s have a look at the TIMER2 registers.

# TCCR2 Register

The Timer/Counter Control Register – TCCR2 is as follows:

TCCR2 Register

Since we will be dealing with the CTC mode later, we are only concerned with Bits2:0 – CS22:20 – Clock Select Bits. Unlike other timers, TIMER2 offers us with a wide range of prescalers to choose from. In TIMER0/1 the prescalers available are 8, 64, 256 and 1024, whereas in TIMER2, we have 8, 32, 64, 128, 256 and 1024!

Clock Select Bit Description

Since we are choosing 256 as the prescaler, we choose the 7th option (110).

# TCNT2 Register

In the Timer/Counter Register – TCNT2, the value of he timer is stored. Since TIMER2 is an 8-bit timer, this register is 8 bits wide.

TCNT2 Register

# TIMSK Register

The Timer/Counter Interrupt Mask – TIMSK Register is as follows. It is a register common to all the timers.

TIMSK Register

Here we are concerned with the 6th bit – TOIE2 – Timer/Counter2 Overflow Interrupt Enable. We set this to ‘1’ in order to enable overflow interrupts.

# TIFR Register

The Timer/Counter Interrupt Flag Register – TIFR is as follows. It is a register common to all the timers.

TIFR Register

Here we are concerned with the 6th bit – TOV2 – Timer/Counter2 Overflow Flag. This bit is set (one) whenever the timer overflows. It is cleared automatically whenever the corresponding Interrupt Service Routine (ISR) is executed. Alternatively, we can clear it by writing ‘1’ to it.

# Code

To learn about I/O port operations in AVR, view this. To know about bit manipulations, view this. To learn how this code is structured, view the TIMER0 post. To learn how to use AVR Studio 5, view this.

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

// global variable to count the number of overflows
volatile uint8_t tot_overflow;

// initialize timer, interrupt and variable
void timer2_init()
{
// set up timer with prescaler = 256
TCCR2 |= (1 << CS22)|(1 << CS21);

// initialize counter
TCNT2 = 0;

// enable overflow interrupt
TIMSK |= (1 << TOIE2);

// enable global interrupts
sei();

// initialize overflow counter variable
tot_overflow = 0;
}

// TIMER0 overflow interrupt service routine
// called whenever TCNT0 overflows
ISR(TIMER2_OVF_vect)
{
// keep a track of number of overflows
tot_overflow++;
}

int main(void)
{
// connect led to pin PC0
DDRC |= (1 << 0);

// initialize timer
timer2_init();

// loop forever
while(1)
{
// check if no. of overflows = 12
if (tot_overflow >= 12)  // NOTE: '>=' is used
{
// check if the timer count reaches 53
if (TCNT2 >= 53)
{
PORTC ^= (1 << 0);    // toggles the led
TCNT2 = 0;            // reset counter
tot_overflow = 0;     // reset overflow counter
}
}
}
}```

So friends, this is how to operate TIMER2 in general mode. Other modes of operation will be discussed in upcoming posts. In the next post, we will learn about the Clear Timer on Compare (CTC) Mode and learn how to apply it to different timers.

1. good approach

2. Hi Mayank,
I am wondering if you are familiar with the various sleep modes of the AVR? I would like to have the AVR enter Power-Save mode for say 5 minutes, then become active again for only 1 minute. In looking at the datasheet, I am not sure if this is possible or not. It looks like it will only do a single overflow on TIMER2.

• Hi Devin,
Sorry, but I haven’t worked with them yet. But you can refer the AVR Library and this document for that. I would suggest you to go through the second pdf, it explains about the three different sleep modes as well as their implementation using C. You will have to set a few bits in the MCUCR register.

3. Excellent tutorial thanks !

4. Hi Mayank,
I am working on PWM generation using 8 bit. But I want to maximum value to TCNT0. Say if I set TCNT0=100, then when I call pwm=100 then it should generate PWM with 100% duty cycle…
Will you help me in this code….

5. plzz i have a prblem with this exercice i need your help:;:
write a program that flashes a LED connected to PB0 and cyclic manner every minute and without using the interrupt ISR () function

• Hi Sana
For this problem if you don’t want to use the Interrupt Service Routine(ISR) functions,
instead you can use the _delay_ms(t), this function will provide you with a delay of t milliseconds.
Just define “ON” and “OFF” state of the pin PB0, each followed by a delay function.
But be sure of the frequency at which your microcontroller is working, as it will decide the clock speed,
which is important to match with real time. :-)

6. Well, it is not quite clear what exactly TCNT0, TCNT1 and TCNT2 work. Could you please make a slightly further explanation on that? Thank you!!!

7. ok!!!! Please, do not bother to explain. It is clear !!!!! Thanx…

• Dear sir..I want a led to glow after one minute at some port if any switch is pressed…pls help…

• I can’t help until you tell me what you have done so far, your methodology and where you are stuck. Thanks!

8. are you using ‘ms’ as MilliSeconds? Or did you mean to use ‘uS’ for microseconds?
ms vs us, which is the one you wanted?

• Hello Moe,
`ms` stands for milliseconds, whereas `us` stands for microseconds. Which instance are you talking about exactly?

9. Hi Mayank,
Like I hv successfully used both (timer0 & timer1) together, so can I also use (timer1 & timer2) together in the same code)?, I have never tried out timer2 till now.., & can this timer2 take a small INPUT reading code in it’s while(1) loop..??…Thanx…

• Hi yes Mayank,
I hv also tested (Timer2) on AtMega8a, it works well & it works same as (timer1 & timer0). What is the difference then in timer2..?? I also put an INPUT pin reading code in the [while(1)] loop, to put two LEDs OFF, it also works,..but again, it is “eractic” & LEDs are also flickering, and at times, no change is seen at all. So U r right, that the (main) stops working while the ISR is doing it’s tedious work, & the AtMega8a is a small chip, so that’s bad programing..
So any suggestion of how to combine INPUT reading code together with timer2..?? Or with any of the three timers. Thanx., Regards…

• Hi Mayank, ….don’t bother about my above ‘input reading code’, question,..as U hv already given that explanation & also given example codes to try out, in ur (timer0) reply box,,..so it’s OK,…-& thanks a lot…

10. Hi Mayank….i am new to embedded pgm….i have some doubt regarding basics…if i need delay for 4 hours with the help of timer then how should be the code look….before writing program to M.C what are the basic things that have to done…….Expecting reply from you…..

• Hello Vysakh,
I’m pretty sure you’re smart enough to read through materials on this website and figure it out yourself! :)

• Hi Vysakh….., learn “timer1”, basics of (16 bit timer) by studying from this very site, & then, if U set the prescaler /1024, U should get a delay of 64 seconds (approx) after each over-flow, & also define a “variable” to count the over-flows. If the (over-flows = 60), then u have a 1 hour delay..!, & if (over-flows = 4×60 counts) of ur variable, then ur delay = 4 hours..!! ..- Mayank may pl. correct me if I missed something…here..??

11. Thanks Max, I am a student and your tutorials are really helpful!

• Thank you Craig! I really appreciate your feedback! :)

12. Its been very nice studying avr under your guidance.

I have already done rtc with timer2 with clk @32.768kHz/128 through interrupt to get real time. Your help was required as i am stuck with the power modes in avr. I could hardly found any helpful link on google.

Hope you could explain this topic for me as you always do.

• Well sir,
I have already visited the two sites earlier and tried mcu entering sleep mode.
Here is what i m struggling/confused with:

1. The site nongnu.com claims (inside some article) to be having achieved less than 1mA in sleep mode, which i couldn’t. Also, the datasheet of Atmega8 and Atmega16 claim only a few uA under sleep modes.

The second problem is that-
2. What i desire is that Atmgega shall remain permanently ON to continue RTC even when external power is OFF. For this i have added a battery connected alone to mcu’s VCC. The ext Vcc is fed to mcu via. a diode to prevent back flow current from battery.
As my premilinary approach, i have extracted a signal from ext Vcc and fed to INT2, so that when power off, an edge trigger shall be detected and ISR(INT2_vect) shall toggle SE bit to 1, thereby sleeping mcu. Same way when ext power is applied a low to high signal at INT2 shall toggle SE bit back to 0, thereby awaking mcu.
Under Sleep Mode(Power-Save), only RTC is desired to operate and off-course the batter is only source, which is why minimizing current consumption is the primary target here.

Thanks and Please feel free to criticise and/or optimize my approach.