My aim is to generate 1msec timer interrupt.
The Device i am using is MC9S12G Family (MC9S12G128).
To get the 1msec interrupt I used channel 0 as a output compare and no output required on the pins. For this I configured following registers (other timer registers are set to default state),
TIOS = 0x01;
TC0 = 0x5D02; /* 1msec value for output compare, Bus clk = 24Mhz, Prescaler = 1 */
TSCR1 = 0xE0;
TIE = 0x01;
TSCR2 = 0x80;
Here Channel 0 will gives the interrupt after output compare value matches that is 1msec.
So here i am not understanding when will be Timer overflow interrupt occurs ? as I have enabled in TSCR2.
Also How to set the Timer Overflow Interrupt after every 1msec ? If i don't want to use channel registers or output compare.
interrupt 8 void CH0_ISR(void)
TC0 = TC0 + 0x5D02;
TFLG1 = 0x01; //clear interrupt flag
interrupt 16 void TOI_ISR(void)
TFLG2 = 0x80; //clear interrupt flag
Any help is appreciated.
Timer counter overflow (TOF) interrupt happens when timer counter overflows from 0xFFFF to 0. The best usage of TOF is to extend timer capture usage to long timeouts, >0xFFFF timer ticks. You can precisely measure long pulse widths or time difference between two pulse edges etc..
You can change TOF rate only changing timer prescaler, so most likely no chance to produce precise 1ms timeouts.
A couple of observations. For a 24 MHz bus clock and a ÷1 prescaler, the value written/added to the timer channel register should be 0x5dc0 = 24000. This would cause an OC interrupt every 1 mS. There's no need to use the timer overflow interrupt. A timer overflow interrupt will be generated every 1 ÷ (24,000,000 ÷ 65536) = 2.73 mS. That is, every time the free running counter overflows from 0xffff to 0x0000.
Adding a constant value to the timer channel register modulo 65536, that is ignoring overflows from the 16-bit addition, will always cause an output compare to occur at the same fixed interval.
If you do not want to use the output compare function for a periodic interrupt, you could use the Realtime interrupt with the CPMURTI register set to 0x9b (see Table 10-11. RTI Frequency Divide Rates for RTDEC=1 in the MC9S12G Family Reference Manual, Rev.1.25). Or the API timer could be used to generate a 1 mS interrupt.
I hope this helps.
Thanks Gordon & Edward for your reply !
One more query is, I am reloading TC0 (TC0 =TC0 + 0x5DC0) in CH0 ISR. So once the count in TC0 crosses to 65536 then it rollover and again start incrementing from that value.
Is there any effect of this rollover in timing ? or how the TC0 16 bit value overflow is taken care.
There is no problem with the TCNT rollover from 0xffff to 0x0000 and the addition to the TC0 register since both are done modulo 65536. For example, after a reset, the TCNT register begins at 0x0000. If 0x5DC0 is written to TC0, an interrupt will occur 1 mS from when the TCNT began counting from reset. Therefore, it is best for the first time TC0 is initialized to add 0x5DC0 to the contents of TCNT:
TC0 = TCNT + 0x5DC0;
This will assure an interrupt occurs 1 mS after the initialization occurs. In the ISR, you will always want to add 0x5DC0 to the value of TC0:
TC0 = TC0 + 0x5DC0;
For an example of the overflow consider the following, assuming an initial TCNT value of 0x0000. When TC0 is initialized, it will contain 0x5DC0. At the first interrupt, when TCNT has incremented to 0x5DC0, adding 0x5DC0 to TC0 it will contain 0xbb80 causing an interrupt exactly 1 mS later when TCNT has incremented to 0xbb80. Now when the second interrupt occurs, the addition of 0x5DC0 to TC0 (0xbb80) will result in TC0 containing 0x1940, because the overflow of the addition is ignored (how C does arithmetic with same size operands). If you consider this this from an absolute value standpoint, the number of TCNT counts between 0xbb80 and 0x1940 is 0x5DC0 or 24000. As Edward mentioned, the timer overflow interrupt is provided for situations where time periods longer than 65536 TCNT counts must be managed.
Again, I hope this helps.