Reputation: 71
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 and 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
Upvotes: 1
Views: 430
Reputation: 1508
I use the arduino framework with setup() and loop() functions. It might not be an optimal choice, but it's easier. Timer 0 is used by wiring.c, which is responsible for delay functions (not _delay_ms() which doesn't use interrupts). This can be disabled, as explained in this post or timer 2 can be used instead. In the latter case, your second code works fine. Could it be that you face a similar problem?
Upvotes: 0