OK, this is not the first time I have used timers by any means, but for some reason I can't figure this one out. Basically I had a 10MHz crystal hooked up to an ATMega48 and was trying to keep accurate time, but every hour or so I'd be loosing a second. On top of that I want multiple interrupts per second anyway, so I set up timer 1 in CTC mode, enabled interrupts on compare with OCRA1, set up the interrupt etc. Still I lost seconds, so figuring perhaps the crystal was bad I changed it to the only other value I had at hand (because Mouser decided not to send me the other 5 values I had ordered :evil:) which was 20MHz.
When I put the power in the result was to be as expected, one seconds worth of interrupts went by in half that time. So I decided to adjust the timer for the new 20MHz clock and see if I could get things going without loosing time. Here is how my calculations broke down:
Prescale by 8 in hardware fuse is off.
Timer Control prescaler is set to 256, so 20MHz / 256 = means 78125 ticks per second (yes?).
Output Compare set to 625, so for every 625 ticks an interrupt will fire and the Timer cleared such that there are 125 interrupts per second.
Here is how I have set the registers in C, which I believe should reflect the above settings for the ATMega48:
TCCR1B |= ((1 << WGM12)); //timer 1 CTC mode TIMSK1 |= (1 << OCIE1A); //enable intterupt on CTC (Output Compare Interrupt Enable on register 1A (OCR1A)) OCR1A = 625; //compare value (16 bits) TCCR1B |= ((1 << CS12) | (1 << CS10)); //timer start. timer at external 20mhz / 256 (78125 counts per second)
However, counting to 125 and incrementing the seconds results in something like 3 seconds per increment. This is obviously not correct, and just to double check I have switched out clock crystals, uCs etc. So I'm pretty sure I'm doing something stupid and it is not the hardware.
I'm catching TIMER1_COMPA_vect by the way, and yes all variables manipulated in the SPI statement are volatile.
So, any ideas?