Прерывания 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.
@cheshircat, 👍0
Обсуждение1 ответ
Лучший ответ:
Я только что попробовал использовать arduino-mk https://github.com/sudar/Arduino-Makefile, и он сработало, поэтому, думаю, я просто буду придерживаться этого.
Лично я бы рекомендовал использовать библиотеку таймеров для получения прерываний. Они объектно-ориентированы и намного чище и эффективнее памяти., @xyz
Значит, это был ваш make-файл, который был неправильным?, @jfpoilpret
Да, это был makefile, @cheshircat
Проблема, вероятно, не в Makefile как таковом, а в том, что ваш ISR должен совпадать с именем чего-то, перечисленного в таблице векторов в исходном файле, помещенном в раздел, помещенный в нужное место картой компоновщика. Использование arduino-ish Makefile включало настройку для такого соответствия имени ISR, которое вы использовали., @Chris Stratton
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Прерывание переполнения Timer0 не работает
- Измерить количество циклов и время цифрового входа
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- Изменчивая переменная не обновляется с таймера ISR
- генерировать два сдвинутых по фазе ШИМ-импульса, запускаемых внешним сигналом с частотным разделением, с помощью Arduino uno?
Можем ли мы увидеть полный вывод
make
?, @Ignacio Vazquez-AbramsЯ бы раскомментировал строки
TCCR1A=0;
TCCR1B = 0;
TCNT1 = 0;
., @GerbenПробовал их раскомментировать, ничего не изменилось, @cheshircat
Кажется, вывод make не соответствует опубликованному вами make-файлу: как первый
avr-gcc
был вызван из вашего make-файла, для меня загадка..., @jfpoilpretОн автоматически генерируется из цели "$(SOURCE).o, @cheshircat