AVR Timers – TIMER2


AVR Series

Dear readers, please note that this is the old website of maxEmbedded. The articles are now no longer supported, updated and maintained. Please visit the new website here and search for this post. Alternatively, you can remove .wordpress from the address bar to reach the new location.

Example: If the website address is http://maxEmbedded.wordpress.com/contact/, then removing .wordpress from it will become http://maxEmbedded.com/contact/.

We apologize for the inconvenience. We just want to give you a better viewing and learning experience! Thanks!

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:Timer CountNow let’s have a look at the TIMER2 registers.

TCCR2 Register

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

TCCR2 Register

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

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

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

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

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.

So till then, grab the RSS Feeds or subscribe to my blog to stay updated! And please don’t forget to leave a reply below. I will be happy to see them! 🙂

27 responses to “AVR Timers – TIMER2

  1. Pingback: AVR Timers – TIMER1 « maxEmbedded·

  2. Pingback: Introduction to AVR Timers « maxEmbedded·

  3. Pingback: AVR Timers – TIMER0 « maxEmbedded·

  4. Pingback: AVR Timers – CTC Mode « maxEmbedded·

  5. Pingback: AVR Timers – PWM Mode – Part I « maxEmbedded·

  6. Pingback: Transition timing·

  7. Pingback: AVR Timers – TIMER0 | maxEmbedded·

  8. 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.

  9. 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….

  10. 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. 🙂

  11. 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!!!

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

  13. 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…

  14. 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…..

    • 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..??

We'd love to hear from you!

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s