I am attempting to program my arduino in plain C, and I've come across some very strange behavior. If I load the following code from the Arduino IDE, it works as expected and toggles Pin 6 every 100ms. However, if I compile it with avr-gcc and then load it with avrdude, no interrupts are run. Here is the C code:
#include <avr/io.h>
#include <avr/interrupt.h>
int main();
void timer1_init();
int main()
{
// connect led to pin PD6
DDRD |= (1 << 6);
PORTD |= (1 << 6);
// initialize timer
timer1_init();
// loop forever
while(1)
{
// do nothing
// whenever a match occurs, ISR is fired
// toggle the led in the ISR itself
// no need to keep track of any flag bits here
// done!
}
}
// initialize timer, interrupt and variable
void timer1_init()
{
/*cli();*/
/*TCCR1A = 0;*/
/*TCCR1B = 0;*/
/*TCNT1 = 0;*/
OCR1A = 24999;
TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10);
TIMSK1 |= _BV(OCIE1A);
sei();
}
ISR (TIMER1_COMPA_vect)
{
// toggle led here
PORTD ^= (1 << 6);
}
And here is the Makefile I'm using to load it onto the arduino:
CC = avr-gcc
CFLAGS = -g -O0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106
SOURCE = test
all: load
$(SOURCE): $(SOURCE).o
$(CC) $(SOURCE).o -o $(SOURCE)
hex: $(SOURCE)
avr-objcopy -O ihex -R .eeprom $(SOURCE) $(SOURCE).hex
load: hex
avrdude -F -V -c arduino -p ATMEGA328P -P /dev/tty.usbmodem1411 -b 115200 -U flash:w:$(SOURCE).hex
clean:
rm -f *.o *.hex
rm -f `find . -perm 755 | perl -pe 's/\.\n//g' | perl -pe 's/\.\/(\w+)\n/1円 /g'`
Is there something that the arduino ide automatically adds to it that makes it work? What am I missing?
Edit: Here is the make output:
avr-gcc -g -O0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -c -o test.o test.c
avr-gcc test.o -o test
avr-objcopy -O ihex -R .eeprom test test.hex
avrdude -F -V -c arduino -p ATMEGA328P -P /dev/tty.usbmodem1411 -b 115200 -U flash:w:test.hex
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e950f
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "test.hex"
avrdude: input file test.hex auto detected as Intel Hex
avrdude: writing flash (196 bytes):
Writing | ################################################## | 100% 0.04s
avrdude: 196 bytes of flash written
avrdude: safemode: Fuses OK (E:00, H:00, L:00)
avrdude done. Thank you.
1 Answer 1
I just tried using arduino-mk https://github.com/sudar/Arduino-Makefile, and it worked, so I guess I'm just going to stick with that.
-
Personally, I would recommend using a timer library to achieve interrupts. They are object oriented and so much cleaner and memory efficient.xyz– xyz2015年01月04日 11:53:09 +00:00Commented Jan 4, 2015 at 11:53
-
So it was your makefile that was incorrect?jfpoilpret– jfpoilpret2015年01月04日 13:38:02 +00:00Commented Jan 4, 2015 at 13:38
-
Yes, it was the makefilecheshircat– cheshircat2015年01月04日 16:01:32 +00:00Commented Jan 4, 2015 at 16:01
-
The issue is probably not the Makefile per se, but that your ISR must match the name of something listed in a vectors table in a source file placed in a section placed in the right place by the linker map. Using an arduino-ish Makefile included a setup for such matching the ISR name you used.Chris Stratton– Chris Stratton2015年01月04日 17:18:36 +00:00Commented Jan 4, 2015 at 17:18
Explore related questions
See similar questions with these tags.
make
output?TCCR1A=0;
TCCR1B = 0;
TCNT1 = 0;
.avr-gcc
got called from your makefile is a mystery to me...