Прерывания TIMER1 CTC не работают с avr-gcc

Я пытаюсь запрограммировать свою Arduino на простом C и столкнулся с очень странным поведением. Если я загружу следующий код из Arduino IDE, он будет работать, как и ожидалось, и переключать контакт 6 каждые 100 мс. Однако, если я скомпилирую его с помощью avr-gcc, а затем загружу с помощью avrdude, прерывания не будут запущены. Вот код C:

#include <avr/io.h>
#include <avr/interrupt.h>

int main();
void timer1_init();

int main()
{
    // подключаем светодиод к пину PD6
    DDRD |= (1 << 6);
    PORTD |= (1 << 6);

    // инициализируем таймер
    timer1_init();

    // цикл навсегда
    while(1)
    {
        // ничего не делать
        // всякий раз, когда происходит совпадение, запускается ISR
        // переключаем светодиод в самом ISR
        // здесь нет необходимости отслеживать какие-либо флаговые биты
        // сделанный!
    }
}

// инициализируем таймер, прерывание и переменную
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)
{
    // переключить светодиод здесь
    PORTD ^= (1 << 6);
}

А вот Makefile, который я использую для загрузки в 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'`

Есть ли что-то, что arduino ide автоматически добавляет к нему, что заставляет его работать? Что я упускаю?

Редактировать: вот результат make:

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.

, 👍0

Обсуждение

Можем ли мы увидеть полный вывод make?, @Ignacio Vazquez-Abrams

Я бы раскомментировал строки TCCR1A=0; TCCR1B = 0; TCNT1 = 0;., @Gerben

Пробовал их раскомментировать, ничего не изменилось, @cheshircat

Кажется, вывод make не соответствует опубликованному вами make-файлу: как первый avr-gcc был вызван из вашего make-файла, для меня загадка..., @jfpoilpret

Он автоматически генерируется из цели "$(SOURCE).o, @cheshircat


1 ответ


Лучший ответ:

0

Я только что попробовал использовать arduino-mk https://github.com/sudar/Arduino-Makefile, и он сработало, поэтому, думаю, я просто буду придерживаться этого.

,

Лично я бы рекомендовал использовать библиотеку таймеров для получения прерываний. Они объектно-ориентированы и намного чище и эффективнее памяти., @xyz

Значит, это был ваш make-файл, который был неправильным?, @jfpoilpret

Да, это был makefile, @cheshircat

Проблема, вероятно, не в Makefile как таковом, а в том, что ваш ISR должен совпадать с именем чего-то, перечисленного в таблице векторов в исходном файле, помещенном в раздел, помещенный в нужное место картой компоновщика. Использование arduino-ish Makefile включало настройку для такого соответствия имени ISR, которое вы использовали., @Chris Stratton