I've run into an issue where, it appears, my interrupt only fires once, then simply refuses to fire again on my ATMega32U2. I have the following (stripped down) code:
void init(void) {
DDRB = 0xff;
PORTB = 0x00;
TCCR0A = (1 << WGM01);
// 1024 prescaler
TCCR0B = ((1 << CS02) | (1 << CS00));
// Interrupt every 4096 clocks
OCR0A = 3;
// Enable timer compare match interrupt
TIMSK0 != (1 << OCIE0A);
}
ISR(TIMER0_COMPA_vect) {
PORTB++;
}
int main(void) {
init();
sei();
while(1);
return 0;
}
When I plug an LED into each pin of PORTB
, the first pin is high, while the rest are low. The most I can deduce from this is PORTB
is incremented to 0x01
by the interrupt firing once, then left alone as the interrupt never fires again using the TIMER0_COMPA_vect
vector.
However, if I replace the compare interrupt with an overflow interrupt (TIMER0_OVF_vect
) and configure the registers differently, it works fine; PORTB
cycles through 0 - 255 very quickly as I'd expect. This is my working code with the type of interrupt I don't want:
// Different timer config
void init(void) {
DDRB = 0xff;
PORTB = 0x00;
TCCR0B |= (1 << CS01);
// Enable timer 0 interrupt
TIMSK0 |= (1 << TOIE0);
}
// This time, it's an OVERFLOW vector, not a compare vector
ISR(TIMER0_OVF_vect) {
PORTB++;
}
int main(void) {
init();
sei();
while(1);
return 0;
}
I've read what there is to read on Google, however the only fixes posted are logical errors that I don't think I have. I've read this forum post and had a look at the timer configuration registers, and they're exactly the same as my first example. I've also read this question, but that didn't help.
I've been following the tutorial on this page (PDF) for the TLC5940 LED driver chip and am on Chapter 4 (refactoring code to use interrupts). Please note that I don't want to use the ready built library; I'm using this as a learning experience.