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.
  • Can we see the full make output? – Ignacio Vazquez-Abrams Jan 2 '15 at 4:56
  • I'd uncomment the lines TCCR1A=0; TCCR1B = 0; TCNT1 = 0;. – Gerben Jan 2 '15 at 16:34
  • I tried uncommenting them, it didn't change anything – cheshircat Jan 2 '15 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 Jan 3 '15 at 7:51
  • It's automatically generated from the target "$(SOURCE).o – cheshircat Jan 3 '15 at 18:10
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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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