AVR Timer Interrupts in C

Timer interrupts are an excellent way of having your AVR do something at a given interval. They can fire off and interrupt what ever else the AVR is doing making for very precise timing. They are one of the best ways to implement custom waveforms for things such as positioning robot servos, dimming LED’s, and driving speakers at different frequencies.

STK500 Setup

For this example, make sure that you have your PORTA jumpered to LEDs, as was discussed in our Port Output guide.

The Interrupt Header

In order to use the built in interrupt features in WinAVR you need to include the interrupt header like this:

The ISR keyword

WinAVR uses the keyword ISR to denote an Interrupt Service Routine. We need to define the ISR for timer1 overflow. You do it like this:

Turning on the Timer Interrupt

In order for the interrupt to fire, you must enable it in the TIMSK register. To enable both timer0 and timer1 interrupts, use the following code in main:

Setup Your Timer

Once you have your ISR defined, and you have enabled the interrupt in TIMSK, you can setup your timer how ever you want. When the timer rolls over, the interrupt will be fired. Here is an example of setting up timer0 to count from 0 to 255, with a divide by 1024 prescaler. This will make the timer0 interrupt fire 30.63 times every second with a frequency of 8.0MHz (8,000,000 / 255 / 1024 = 30.63).




Enable Interrupts

This step is easy, simply call sei(); to turn on the global interrupt enable flag.

AVR Timer Interrupts Example

Here is a simple example that turns on both timer0 and timer1. It accomplishes the following:

  • Sets up timer0 in divide by 1024 mode, counting from 0 to 255
  • Sets up timer1 in divide by 1024 mode, counting from 0 to 65,535
  • On timer0 interrupt, toggles PORTA bit 0.
  • On timer1 interrupt, toggles PORTA bit 1.

You will see PORTA bit 0 blinking on and off 15 times / second, and PORTA bit 1 blinking on and off every 8.3 seconds.

You can download the complete source code here.

This program compiles down to 246 bytes for us.

Next Up, A More Complicated Example

If you want to see some more timer interrupt examples, then check out our More Complex Timer Interrupt Functions guide.

Or head back to our index of AVR Guides here.

5 comments

  • Prof. Dattaraj Vidyasagar

    Wow.
    Thank you so much.
    You site is just great
    Thanks
    Tell me how to subscribe to your updates?

  • When I ran this code, I getting an error ? as

    In function __vector_16':
    49: multiple definition of
    __vector_16′
    /home/circuits/123D-Circuits-arduino-compiler/build/sketch.ino:17: first defined here
    error: ld returned 1 exit status

    volatile uint16_t tot_overflow;
    void timer0_init()
    {
    TCCR0B |= (1<<CS02);
    TCNT0 =0;
    TIMSK0 |= (1 << TOIE0);
    sei();
    tot_overflow =0;
    }
    void setup()
    {
    timer0_init();
    DDRD |= (1<= 245)
    {
    if(TCNT0>=25)
    {
    PORTD ^= (1<<2);
    TCNT0=0;
    tot_overflow =0;
    }
    }
    }

    ——————————————————————————————————
    but when I do small modification in the code, it gets executed
    modifications were instead of void loop – I defined int main() and I called setup function from main function?

    Can you tell me what would be the problem?

  • When I ran this code, I getting an error ? as

    In function __vector_16′:
    49: multiple definition of
    __vector_16′
    /home/circuits/123D-Circuits-arduino-compiler/build/sketch.ino:17: first defined here
    error: ld returned 1 exit status

    volatile uint16_t tot_overflow;
    void timer0_init()
    {
    TCCR0B |= (1<<CS02);
    TCNT0 =0;
    TIMSK0 |= (1 << TOIE0);
    sei();
    tot_overflow =0;
    }
    void setup()
    {
    timer0_init();
    DDRD |= (1<= 245)
    {
    if(TCNT0>=25)
    {
    PORTD ^= (1<<2);
    TCNT0=0;
    tot_overflow =0;
    }
    }
    }

    but when I do small modification in the code, it gets executed
    modifications were instead of void loop – I defined int main() and I called setup function from main function?

    Can you tell me what would be the problem?

  • I got an error

    TIMSK is undeclared
    TCCR0 is undeclared

    can help me

  • Hi

    Someone kindly can explain me how have been calculated the values below.

    – PORTA bit 0 blinking on and off 15 times / second
    – PORTA bit 1 blinking on and off every 8.3 seconds

Leave a Reply

Your email address will not be published. Required fields are marked *

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