2020年12月23日星期三

Why does my ISR declaration break my program?

I am trying to make two LEDs blink on my Arduino Uno R3 (for learning purposes). I use avr-gcc and avrdude to compile and load my program.

The first one I make blink within a while loop in main. I am trying to use Timer0 to turn the second one on and off.

First, the code that works :

#include <avr/io.h>  #include <util/delay.h>    int main() {      TCCR0B |= (1 << CS02) | (1 << CS00);      TIMSK0 |= (1 << TOIE0);        DDRD = 1 << PD3;      DDRB = 1 << PB5;      PORTB = 0;        while(1) {          PORTD ^= 1 << PD3;          _delay_ms(500);      }      return 0;  }  

As expected, this code makes my LED blink on and off, and start again every second. I am also setting up (but not using) the second LED abd the timer.

Now, the issues start when I add an interrupt vector :

...  #include <avr/interrupt.h>    volatile uint8_t intrs;    ISR(TIMER0_OVF_vect) {      if (++intrs >= 62) { // meant to execute every second          PORTB ^= (1 << PB5);          intrs = 0;      }  }    int main() {      intrs = 0;      ... // old setup      sei();      while(1) { ... }  }  

Now, none of the leds blink. Even weirder, none of them blink when I remove the sei(). The only way I've found to make the first LED blink again is to comment out the ISR declaration, or to mark it ISR_NAKED.

So, what gives ?

PS : I use a makefile to compile & load. When I run it, it looks like this:

$ make  avr-gcc -c -Os -DF_CPU=16000000UL -mmcu=atmega328p -Wall -Wextra main.c  avr-gcc -o prog.elf main.o   avr-objcopy -O ihex -R .eeprom prog.elf prog.hex  avrdude -C/etc/avrdude.conf -v -V -carduino -patmega328p -P/dev/ttyACM0 -b115200 -D -Uflash:w:prog.hex  .. # avrdude logs  
https://stackoverflow.com/questions/65427371/why-does-my-isr-declaration-break-my-program December 24, 2020 at 12:10AM

没有评论:

发表评论