Search code examples
timerarduinointerruptatmegamicrochip

Problem with toggle led on Arduino nano Atmega328P with timer/counter0 interrupt


I try to toggle the LED on Arduino nano ATmega328P without success. (Timer 0 is 8bit timer)

I managed to execute it with Timer 1 with code from here.

#define ledPin 13
void setup() {
  pinMode(ledPin, OUTPUT);
  cli(); // disable interrupts
  TCCR0A = 0;
  TCCR0B = 0;
  TCCR0B |= (1 << CS02 | 1 << CS00); //clkI/O/1024
  TIMSK0 = 0;
  TIMSK0 |= (1 << TOIE0); // Overflow Interrupt Enable
  TCNT0 = 0;
  sei(); // enable interrupts
  Serial.begin(9600);
}

ISR(TIM0_OVF_vect) {
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void loop() {

}

I also tried to change the interrupt vector to: TIMER0_OVF_vect

and got this error:

Arduino: 1.8.9 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

wiring.c.o (symbol from plugin): In function `__vector_16':

(.text+0x0): multiple definition of `__vector_16'

sketch\tests.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I expect the led to toggle.


Solution

  • Your first block of code with:

    ISR(TIM0_OVF_vect) {
        digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
    }
    

    has the wrong ISR name. TIM0_OVF_vect is only valid for some ATtiny microcontrollers. You can find a complete list of interrupts and which controllers they are used with here.

    You then tried to change it to use TIMER0_OVF_vect, which is valid for the ATMEGA328P, but you cannot use this with Arduino, because Arduino ATMEGA328P builds use Timer0 for millis() and related timing. This is why you get a multiple definition of error - the linker is telling you that there are two TIMER0_OVF_vect ISRs defined by your program (one by your sketch, one in wiring.c).

    Timer2 is not used by default, so you should be able to use that instead. The only default Arduino library that used Timer2 is the Tone library.