For many months I have been using software timers which were running 2x too fast without me knowing it.
I followed an instructable to set up the registers and according to the calculations the ISR should be running @ 1kHz but somehow it is running @2kHz
void initTimers()
{
TCCR2B = 0;// same for TCCR2B
TCNT2 = 0;//initialize counter value to 0
// set compare match register for 1khz increments
OCR2A = 249;// = (16*10^6) / (1000*64) - 1 (must be <256)
// turn on CTC mode
TCCR2A |= (1 << WGM21);
// Set CS21and and CS20 bit for 64 prescaler
TCCR2B |= (1 << CS20);
TCCR2B |= (1 << CS21);
TCCR2B &= ~(1 << CS22);
// enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
}
This formula should work, but it does not.
compare match register = (1610^6) / (100064) - 1 = 249
I am using an arduino Nano with the old bootloader and it is running @16MHz.
Meanwell I managed to fix the frequency this by taking a 256 prescaler and a compare match register of:
reg = (1610^6) / (1000256) - 1 = 61.5 (I used 61) because of that 0.5 it is not exactly 1kHz but I can live with it.
However I really like to know why the first ISR settings are not working for me? I ran the math five times but I am not seeing what I did wrong here.
You are setting a bit in TCCR2A without clearing all the bits first. Since the Arduino library sets up the timers for PWM it is likely a bit is set already.
Either add this at the top where you set TCCR2B to zero:
TTCR2A = 0;
Or change the code to set the whole register instead of one bit:
Blackfin:
You're setting the prescaler to /32, not /64:
TCCR2B |= (1 << CS20);
TCCR2B |= (1 << CS21);
TCCR2B &= ~(1 << CS22);
This gives 250x2uS == 500uS period or 2kHz.
Use
TCCR2B |= _BV(CS22);
to set 0b100 for the prescaler (/64) to get 1kHz.
I agree it looks that way but according to the datasheet I am setting the correct prescaler bits. It clearly says that bits CSx0 and CXs1 must be 1 and bit CSx2 must be 0 for a 64 prescaler.
Since the Arduino library sets up the timers for PWM it is likely a bit is set already.
This makes much sense. And I will try out to clear the register first. It remains however strange that with a different prescaler and compare match registers it works well. You would expect a similar bug.
I will try the clearing the register now. Thanks for the answers.
Bas