i’ve setup a timer on an atmega168 in CTC mode since I want an interrupt generated every 1e-4 sec. if my clock is @ 8mhz and i prescale by 8 so it counts every 1e-6 sec, so if i set output compare register to 99 (not 100, right?) it will generate an interrupt every 1e-4 sec?
second question… i’m running a short code inside the interrupt call and before i actually start running it, i stop the counter (by clearing all prescaler select bits) and reset TCNT1 to 0. is this really needed? do i need to stop it at all? and what about resetting the TCNT1 value?
space cake:
i’ve setup a timer on an atmega168 in CTC mode since I want an interrupt generated every 1e-4 sec. if my clock is @ 8mhz and i prescale by 8 so it counts every 1e-6 sec, so if i set output compare register to 99 (not 100, right?) it will generate an interrupt every 1e-4 sec?
second question… i’m running a short code inside the interrupt call and before i actually start running it, i stop the counter (by clearing all prescaler select bits) and reset TCNT1 to 0. is this really needed? do i need to stop it at all? and what about resetting the TCNT1 value?
thanks!
More conventional to say timer period in mSec or uSec.
FYI: there are quite a few free “AVR Calc” programs for windows on avrfreaks.net. You enter the osc freq and so on and it’ll calculate the settings for timers and the UARTs.
Your goal is a 100 microsecond interval? Arguably, too high a frequency for most uses - the ratio of this interval to the time to save and restore registers is unfavorable. Depends on what your goal is and if you need that high rate.
Most apps I’ve done use 1, 10 or 100 millisecond interrupt rates. Even 1mSec is uncomfortably high, on an 8MHz CPU. Especially if the interrupt service routine does nothing useful on most interrupts.
space cake:
i’ve setup a timer on an atmega168 in CTC mode since I want an interrupt generated every 1e-4 sec. if my clock is @ 8mhz and i prescale by 8 so it counts every 1e-6 sec, so if i set output compare register to 99 (not 100, right?) it will generate an interrupt every 1e-4 sec?
That sounds right, not sure about the value, I thought it counts backwards?
space cake:
second question… i’m running a short code inside the interrupt call and before i actually start running it, i stop the counter (by clearing all prescaler select bits) and reset TCNT1 to 0. is this really needed? do i need to stop it at all? and what about resetting the TCNT1 value?
This is what I would do
/*
At 8MHz clock : 8bit overflow 16bit overflow
tClk = 125 nS 31.8 uS 8.19 mS
tClk/8 = 1 uS 255 uS 65.53 mS
tClk/64 = 8 uS 2.04 mS 524.28 mS
tClk/256 = 32 uS 8.16 mS 2.097 S
tClk/1024 = 128 uS 32.64 mS 8.388 S
*/
TCCR1A = 0;
TCCR1B = 2; // tClk/8
TIMSK = (1<<TOIE1);
TCNT1 = 0xFF9C; //(From AVR Calc)
ISR(TIMER1_OVF_vect)
{
TCNT1 = 0xFF9C; //(From AVR Calc)
debug_printf("Testing...\r\n");
}
IIRC, compare match counts from zero to n, resets to zero and sets interrupt flag.
There’s other modes where you pre-load n and it counts up and interrupts on overflow (wrap to 0). That’s the mode I’ve used most. So n is 256-x for an 8 bit counter.
CTC mode is clear timer compare. the counter will automatically clear the count value for you, no need to do it youself in code, you’ll only mess up the timing.
yes, you also need to count to n-1, since the 0 is a valid count to the counter hardware. (you count 1, 2, 3… the timer counts 0, 1, 2…)
as for 100uS being to fast an interrupt rate - with an 8Mhz system clock, a 100uS interrupt rate gets you 800 clocks between interrupts. i’d be more than comfortable with that amount of time to get things done.
i’d do a the following:
uint16_t timer100uS; // just counts 100uS intervals
where TIMER100US_TESTPOINT_TOGGLE toggles a test point or something to view the timing. should be spot on 100uS if you’re running off a crystal, and might be a bit off if you’re running off the internal RC.
Liencouer:
CTC mode is clear timer compare. the counter will automatically clear the count value for you, no need to do it youself in code, you’ll only mess up the timing.
yes, you also need to count to n-1, since the 0 is a valid count to the counter hardware. (you count 1, 2, 3… the timer counts 0, 1, 2…)
as for 100uS being to fast an interrupt rate - with an 8Mhz system clock, a 100uS interrupt rate gets you 800 clocks between interrupts. i’d be more than comfortable with that amount of time to get things done.
i’d do a the following:
uint16_t timer100uS; // just counts 100uS intervals
where TIMER100US_TESTPOINT_TOGGLE toggles a test point or something to view the timing. should be spot on 100uS if you’re running off a crystal, and might be a bit off if you’re running off the internal RC.
thank you very much for the answer. i think this covers everything i wanted to know!
i decided to go with 9456Hz for the timer.
each sample with the internal ADC (125kHz clock) is 13 cycles or 1.04e-4 sec and my loop operation takes 14 cycles @ 8MHz or 1.75e-6 sec. so the total is 1.0575e-4 sec which is just under 9456Hz so i’ll set OCR1A=105 and should be good to go!