I tried to create a CTC timer interrupt on my ATmega32U4 leonardo board. When I continuously check the value of OCF1A
I have no problem detecting when the output reaches the desired value, however once I move the code into an interrupt, the interrupt never triggers.
Timer setup:
#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
}
The loop that works:
setupTimer();
for (;;) {
if (TIFR1 & (1 << OCF1A)) {
PORTC ^= (1 << PORTC7);
TIFR1 = (1 << OCF1A);
}
}
The interrupt that does not work:
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect) {
PORTC ^= (1 << PORTC7);
}
I must be missing something as from what I have seen in the tutorials the above code should work. One interesting observation here is that if I have both the loop and the interrupt in my code at once if I call sei()
, the LED does not blink as if the OCF1A
register was cleared prematurely.
I'm pretty sure it is irrelevant in this case but the fuses are as follows: E:CB, H:D8, L:FF.
I use avr-g++
to compile and the code is spread out between several files.
_BV()
macro for bitmasks instead of manually shifting 1. – Cactus