Pages Menu
TwitterRssFacebook
Categories Menu

Posted by on Jun 28, 2011 in Atmel AVR, Microcontrollers | 152 comments

AVR Timers – TIMER1

AVR Timers – TIMER1

AVR SeriesHello folks! Welcome back! In this tutorial, we will come across TIMER1 of the AVR. I hope that you have read and understood the previous posts:

So basically, in this tutorial, we will do whatever we did in the previous one. In the TIMER0 tutorial, we generated a timer running at the CPU frequency. We then modified the code to include prescalers, and once again modified the code to include interrupts.

Now that you are aware of the concepts, we will deal with TIMER1 in a short and snappy way. Whatever we did in the previous TIMER0 tutorial, we will do the same here. Thus, we will discuss only one problem statement which will include both, prescalers and interrupts.

Once we are done with this, we can proceed to the CTC and PWM modes of operations in subsequent posts.

Problem Statement

Okay, let’s make it loud and clear. We need to flash an LED every 2 seconds, i.e. at a frequency of 0.5 Hz. We have an XTAL of 16 MHz.

Methodology – Using prescaler and interrupt

Okay, so before proceeding further, let me jot down the formula first.Timer CountGiven that we have a CPU Clock Frequency of 16 MHz. At this frequency, and using a 16-bit timer (MAX = 65535), the maximum delay is 4.096 ms. It’s quite low. Upon using a prescaler of 8, the timer frequency reduces to 2 MHz, thus giving a maximum delay of 32.768 ms. Now we need a delay of 2 s. Thus, 2 s ÷ 32.768 ms = 61.035 ≈ 61. This means that the timer should overflow 61 times to give a delay of approximately 2 s.

Now it’s time for you to get introduced to the TIMER1 registers (ATMEGA16/32). We will discuss only those registers and bits which are required as of now. More will be discussed as and when necessary.

TCCR1B Register

The Timer/Counter1 Control Register B– TCCR1B Register is as follows.

TCCR1B Register

TCCR1B Register

Right now, only the highlighted bits concern us. The bit 2:0 – CS12:10 are the Clock Select Bits of TIMER1. Their selection is as follows.

Clock Select Bits Description

Clock Select Bits Description

Since we need a prescaler of 8, we choose the third option (010).

TCNT1 Register

The Timer/Counter1 – TCNT1 Register is as follows. It is 16 bits wide since the TIMER1 is a 16-bit register. TCNT1H represents the HIGH byte whereas TCNT1L represents the LOW byte. The timer/counter value is stored in these bytes.

TCNT1 Register

TCNT1 Register

TIMSK Register

The Timer/Counter Interrupt Mask Register – TIMSK Register is as follows.

TIMSK Register

TIMSK Register

As we have discussed earlier, this is a common register for all the timers. The bits associated with other timers are greyed out. Bits 5:2 correspond to TIMER1. Right now, we are interested in the yellow bit only. Other bits are related to CTC mode which we will discuss later. Bit 2 – TOIE1 – Timer/Counter1 Overflow Interrupt Enable bit enables the overflow interrupt of TIMER1. We enable the overflow interrupt as we are making the timer overflow 61 times (refer to the methodology section above).

TIFR Register

The Timer/Counter Interrupt Flag Register – TIFR is as follows.

TIFR Register

TIFR Register

Once again, just like TIMSK, TIFR is also a register common to all the timers. The greyed out bits correspond to different timers. Only Bits 5:2 are related to TIMER1. Of these, we are interested in Bit 2 – TOV1 – Timer/Counter1 Overflow Flag. This bit is set to ‘1’ whenever the timer overflows. It is cleared (to zero) automatically as soon as the corresponding Interrupt Service Routine (ISR) is executed. Alternatively, if there is no ISR to execute, we can clear it by writing ‘1’ to it.

Code

Now that we are aware of the methodology and the registers, we can proceed to write the code for it. To learn about I/O port operations in AVR, view this. To know about bit manipulations, view this. To learn how to use AVR Studio 5, view this. To learn how this code is structured, view the previous TIMER0 post.

#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 timer1_init()
{
    // set up timer with prescaler = 8
    TCCR1B |= (1 << CS11);
 
    // initialize counter
    TCNT1 = 0;
 
    // enable overflow interrupt
    TIMSK |= (1 << TOIE1);
 
    // enable global interrupts
    sei();
 
    // initialize overflow counter variable
    tot_overflow = 0;
}
 
// TIMER1 overflow interrupt service routine
// called whenever TCNT1 overflows
ISR(TIMER1_OVF_vect)
{
    // keep a track of number of overflows
    tot_overflow++;
 
    // check for number of overflows here itself
    // 61 overflows = 2 seconds delay (approx.)
    if (tot_overflow >= 61) // NOTE: '>=' used instead of '=='
    {
        PORTC ^= (1 << 0);  // toggles the led
        // no timer reset required here as the timer
        // is reset every time it overflows
 
        tot_overflow = 0;   // reset overflow counter
    }
}
 
int main(void)
{
    // connect led to pin PC0
    DDRC |= (1 << 0);
 
    // initialize timer
    timer1_init();
 
    // loop forever
    while(1)
    {
        // do nothing
        // comparison is done in the ISR itself
    }
}

So folks, this is how to apply the basic timer concepts for TIMER1. Please note that if you learn the basics, everything will be easy. If you find yourself struggling with the code, then please visit the TIMER0 tutorial, clear your concepts and give it a try again. If still you don’t get it, I will be glad to help you! :)

In my next post, we will learn how to apply the same concepts to TIMER2. It is, once again, an 8-bit timer. Thus all the TIMER2 registers are similar to TIMER0. After that, we move towards the interesting part, the Clear Timer on Compare (CTC) mode!

Till then, grab the RSS Feeds or subscribe to my blog to stay updated! Also, post your responses below. I am awaiting for them! :)

152 Comments

  1. Hi, I am simulating the Timer1 example in proteus 8. I am using Atmega328P_PU. My code is not lighting up the led and I wonder where or what the problem might be. The simulation with Timer0 worked perfectly but with Timer1, the simulation had no notable change rather it was not lighting the led.
    Here is my code: (code removed by admin)

    Kindly assist me in this.

    Thank you in advance.

    • Try it out in hardware. Sometimes simulators are not able to model timer properly since timer is a property of the hardware and depends upon how the hardware is configured.

  2. “The following HEADER FILES is sufficient for this program or else we have to include some more HEADRE FILES.”

    • Ajay, is that supposed to be a question? I don’t understand.

  3. hi, Thanks for the tutorial.It is really helpful. I want to ask one thing that if we use if (tot_overflow >= 61) condition in while loop ( In main function), then whether it will give any problem ?

    • Hi Anjali,
      Yes, it will be huge problem, the program won’t work! If you write the condition in the while loop in main, there will never be a time when that condition will be true since the micro-controller will reset after the main function terminates, resulting in defaulting of all registers. Basically, tot_overflow will never be able to reach 61 (or greater) since the micro-controller will always reset before it can.
      Hope this helps!

  4. This website is really helpful for my lab. And it really help for my uni study,too.

    • Thanks ;)

      Keep reading :D

  5. hi…
    i have a problem that when i want to count a thing in 10 second the T=25Ms and its the max T and overflow how cn i achieve 10 second…

    • Sajad,
      There are several ways to do it. Simplest method would be to fire an interrupt whenever the timer overflows. In the overflow ISR, keep track of a counter. Somewhere else in your code, you need to monitor for this counter and do whatever you want with it.

  6. A real time interrupt need to be generated at every 0.5 seconds.Describe how this be achieved using HCS12 microcontroller works with 16MHz crystal. write the C function to activate RTI with initializing the necessary register .

    • This is not a homework forum Imran. Please do it yourself. Thank you! :)

  7. Really nice tutorial series. Very good work.

    One question : Can external clock source be prescaled?

    • I can’t think of reason why it cannot. :)
      Thanks!

  8. Thank you very much for your Pervasive tutorial

  9. Hi,
    Thanks for the great article! It helped me a lot. Although, TIMSK should be changed to TIMSK1 as we work with Timer1 here. Otherwise, code won’t compile because there is no definition for TIMSK in header file.

    • Really? I don’t think you’re using ATmega16/32.

  10. it only works if I move the following code into the while loop

    if (tot_overflow >= 61)
    {
    PORTC ^= (1 << 0);
    TCTN1 = 0;
    tot_overflow = 0; // reset overflow counter
    }

    I wonder why ?

  11. sir can you send that header and source file ???

  12. sir can you send that avr interrupt header and source file ???

  13. thx max .can we use overflow and CTC mode on the same program

  14. hi max my question is can we use overflow on CTC mode because i program my led to toggle first for 50ms now i wan wan to make it toggle for 1 s and so on what can i do

  15. Hi.
    Thank you for your so interestings posts.
    You have script, for TIFR:
    “This bit is set to ‘1’ whenever the timer overflows. It is cleared (to zero) automatically as soon as the corresponding Interrupt Service Routine (ISR) is executed. Alternatively, if there is no ISR to execute, we can clear it by writing ‘1’ to it”.

    Clear writing with ‘1’??? Is that correct?

  16. I must say these series is the best timer tutorial on web.

    Actually I was trying to understand this logic in the ISR

    ISR(TIMER1_COMPA_vect)
    {
    uint16_t nTemp; // Temporary storage

    nTemp = TCNT1; // Get current time
    nTemp -= OCR1A; // Subtract interrupt time

    if (nTemp < (TICKS_PER_MSECOND/2)) // If more than half period left
    {
    OCR1A += (TICKS_PER_MSECOND); // Add Offset to OCR1A relative
    }
    else
    {
    OCR1A = TCNT1 + (TICKS_PER_MSECOND); // Set OCR1A to 1 ms absolute
    }
    }

  17. The maximum delay with a prescaler of 1024 should be 4.19424s, shouldn’t it?

  18. Hi, I’m wondering If I understood everything ok…

    Frequency = 16 MHz, 16-bits timer (MAX = 65535). Max delay (65535), so we have 65535/16000000Hz = 4.09ms
    After using prescaler = 8, we have 65535/2000000Hz = 0,032767 = 32,767ms
    We are interested about 2s, we have 2/0,032767 = 61,037 = 61

    Is it ok, or I’m wrong ?

    Please help me :)

  19. Wondering if there such a thing as an Overflow Compare Match (like Output Compare Match) in other controllers? Just curious :)

    • Yes, it’s pretty standard in all microcontrollers. Don’t buy one if it doesn’t has that. :)

Trackbacks/Pingbacks

  1. Timer Pada Mikrokontroler AVR - […] TIMER1, 16-bit timer […]

Leave a Reply

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

%d bloggers like this: