0

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.
5
  • Can we see the full make output? Commented Jan 2, 2015 at 4:56
  • I'd uncomment the lines TCCR1A=0; TCCR1B = 0; TCNT1 = 0;.
    – Gerben
    Commented Jan 2, 2015 at 16:34
  • I tried uncommenting them, it didn't change anything
    – cheshircat
    Commented Jan 2, 2015 at 17:25
  • It seems the make output does not match the makefile you posted: how the first avr-gcc got called from your makefile is a mystery to me...
    – jfpoilpret
    Commented Jan 3, 2015 at 7:51
  • It's automatically generated from the target "$(SOURCE).o
    – cheshircat
    Commented Jan 3, 2015 at 18:10

1 Answer 1

0

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.

4
  • Personally, I would recommend using a timer library to achieve interrupts. They are object oriented and so much cleaner and memory efficient.
    – xyz
    Commented Jan 4, 2015 at 11:53
  • So it was your makefile that was incorrect?
    – jfpoilpret
    Commented Jan 4, 2015 at 13:38
  • Yes, it was the makefile
    – cheshircat
    Commented 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. Commented Jan 4, 2015 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.