Я попытался создать прерывание таймера CTC на моей плате ATmega32U4 leonardo. Когда я постоянно проверяю значение OCF1A
, я без проблем определяю, когда выход достигает желаемого значения, однако, как только я помещаю код в прерывание, прерывание никогда не срабатывает.
Настройка таймера:
#include <avr/io.h>
void setupTimer()
{
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= ((0 << CS10) | (0 << CS11) | (1 << CS12)); // set up prescaler
OCR1A = 6249; // 100 ms set up output compare value for interrupt
TIMSK1 |= (1 << OCIE1A); // enable interrupt on clock compare
}
Цикл, который работает:
setupTimer();
for (;;) {
if (TIFR1 & (1 << OCF1A)) {
PORTC ^= (1 << PORTC7);
TIFR1 = (1 << OCF1A);
}
}
Прерывание, которое не работает:
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect) {
PORTC ^= (1 << PORTC7);
}
Я должен что-то упустить, так как из того, что я видел в учебниках, приведенный выше код должен работать. Одно интересное наблюдение заключается в том, что если в моем коде одновременно есть цикл и прерывание, то при вызове sei()
светодиод не мигает, как если бы регистр OCF1A
был очищен преждевременно.
Я почти уверен, что это не имеет значения. в этом случае предохранители следующие: E:CB, H:D8, L:FF.
Я использую avr-g++
для компиляции, и код распределен между несколькими файлами.
_BV()
для битовых масок вместо ручного сдвига 1. - person Cactus   schedule 17.12.2015