Jump to content

I have problem with interrupt on my Atmega328p. I use Arduino Nano 16 Mhz 5V, so it shoudn't be a hardware problem.

 

Here is the date sheet of atmega328p

This is my code:

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

volatile uint16_t counter;

int main(void)
{
    DDRB |= (1<<PB5);

    TCCR1B |= (1 << CS10);          // set prescaler to 1
    TIMSK1 |= (1 << TOIE1);         // set overflow interrupt
    sei();                          // enable interrupts


    while (1)
    {
        // Main loop
    }
}

ISR (TIMER1_OVF_vect)
{
    counter++;
    if (counter > 200)
    {
        counter = 0;
        PORTB ^= _BV(PB5);
    }
}

I want to have intterupt as often as possible, but with this configuration diode blinks every 1 second - this is too slow, I need at least every 10us or less if it is possible. It can be any other Timer, I don't care.

 
Link to comment
https://linustechtips.com/topic/799263-atmega328p-timer-wrong-configuration/
Share on other sites

Link to post
Share on other sites

11 hours ago, nanawhite107 said:

I have problem with interrupt on my Atmega328p. I use Arduino Nano 16 Mhz 5V, so it shoudn't be a hardware problem.

 

Here is the date sheet of atmega328p

This is my code:


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

volatile uint16_t counter;

int main(void)
{
    DDRB |= (1<<PB5);

    TCCR1B |= (1 << CS10);          // set prescaler to 1
    TIMSK1 |= (1 << TOIE1);         // set overflow interrupt
    sei();                          // enable interrupts


    while (1)
    {
        // Main loop
    }
}

ISR (TIMER1_OVF_vect)
{
    counter++;
    if (counter > 200)
    {
        counter = 0;
        PORTB ^= _BV(PB5);
    }
}

I want to have intterupt as often as possible, but with this configuration diode blinks every 1 second - this is too slow, I need at least every 10us or less if it is possible. It can be any other Timer, I don't care.

 

Your current code runs timer 1 with no prescaler in "normal" mode, meaning it simply counts up to it's maximum value (65535 because it's a 16 bit timer) then overflows to 0, setting the overflow flag and triggering the interrupt.

 

The math: 65536 counts for 1 overflow times 201 calls to the interrupt routine before "counter > 200" = 13172736 counts between each toggle of the LED. At 16Mhz that makes for 0,823296 seconds.

 

If you want it triggered every 10µS then you need a interrupt every 10µS / 0.0625µS per clocktick = 160 clockticks. That can't be done in normal mode, you'll need to use "Clear Timer on Compare Match (CTC) Mode". You'll need to:

  • Configure TCCR1A and TCCR1B for one of the CTC modes with no prescaler.
  • Load either OCR1A or ICR1, depending on which CTC mode you chose - 4 or 12, with the compare value, 160.
  • Enable the timer 1 interrupt on compare match in stead of the overflow interrupt.
  • Change the interrupt routine to compare match in stead of overflow (TIMER1_COMPA_vect or TIMER1_COMPB_vect, depending on which you chose).
  • Remove the counter from the interrupt routine.
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×