I'm trying to understand how to fully use the COMPB vector ISR of Timer0 on the ATMega328 (standard Arduino core). I realize it will make delay() and millis() not work but that's ok by me. I've setup some test code that should output a 244Hz signal on D4 and 488Hz on D5 (note, this is running at 8MHz). But D5 (COMPB) is always what D4 (COMPA) is. Any thoughts? Code below:
#include <avr/interrupt.h>
volatile bool stateA = false;
ISR(TIMER0_COMPA_vect)
{
if (stateA)
PORTD |= _BV(PIND4);
else
PORTD &= ~(_BV(PIND4));
stateA = !stateA;
}
volatile bool stateB = false;
ISR(TIMER0_COMPB_vect)
{
if (stateB)
PORTD |= _BV(PIND5);
else
PORTD &= ~(_BV(PIND5));
stateB = !stateB;
}
void setup()
{
DDRD |= _BV(PIND4) | _BV(PIND5);
//set timer0 interrupt at 2kHz
TCCR0A = 0;// set entire TCCR2A register to 0
TCCR0B = 0;// same for TCCR2B
TCNT0 = 0;//initialize counter value to 0
// set compare match register for 2khz increments
OCR0A = 255;//244Hz
OCR0B = 127;//488Hz
// turn on CTC mode
TCCR0A |= (1 << WGM01);
// Set CS01 and CS00 bits for 64 prescaler
TCCR0B |= (1 << CS01) | (1 << CS00);
// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0B) | (1 << OCIE0A);
interrupts();
}
Update: After thinking about it, I'm realizing that it's not that I need two separate frequencies (though I just kinda wanted to know how, so this is good stuff) but I just need two separate interrupts, only using Timer0 (1 & 2 are already in use elsewhere). They can be the same frequency, most likely. I probably could put all the functionality I need in the same TIMER0_COMPA_vect, however I was trying to use that in a library I was writing and was trying to keep the functionality separate... this may not be possible.
if (stateA) ...
withPORTD ^= _BV(PIND4);
(exclusive or of this bit) and removing thosevolatile
state variables.