View previous topic :: View next topic |
Author |
Message |
mkr
Joined: 08 Aug 2006 Posts: 49
|
timer1 interrupting in-correctly |
Posted: Thu Aug 31, 2006 6:50 pm |
|
|
I am facing a nightmare to calculate the timer values for timer1. I know that there are tons of info available in this forum, but I am totally confused. How do we calculate the set_timer1 value. This is my hardware .....
1.uP is 18f8722
2.crystal freq is 16MHz,
The timer setup is -> setup_timer1(T1_INTERNAL | T1_DIV_BY_4);
I want to use the timer1 isr to interrupt the routine every 1millisec. My question is... how will I calculate set_timer1(value). This is how I did it but, i dont get the interrupt every 1ms, sometime after it.
FOSC=16Mz
Instruction cycle = 4.
Fillup cycle = FOSC/Instruction cycle = 16Mhz/4 = 4Mhz.
Hence, Time = 1/Frequency = 1/4Mhz = 0.25 uSec.
Required_ISR_timer_value = 1ms.
value1 = Required_ISR_timer_value/Time = 1ms/.25us = 4000 counts.
Now......
value = 65536 - value1 = 65536 - 4000 = 61536 count.
Therefore set timer value is - > set_timer1(61536);
IS this calculation correct. The interrupt routine is visited 4000 times to make 1ms sec. _________________ Thanks
mkr |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Thu Aug 31, 2006 8:30 pm |
|
|
You're missing a factor of 4....
The crystal frequency for the pic is internally divided by 4 to get the "system clock". You have no control over this divide by 4.
So timer 1 increments at a rate of 4 MHz (= 16 MHz / 4), PLUS the additional divide by 4 in your timer 1 setup. Timer 1 then increments (counts) at a rate of 1 count every 1 microsecond, which is why your math is out. To make your math correct, set the timer 1 "div by 4" to one.
http://www.ccsinfo.com/forum/viewtopic.php?t=22467&highlight=timers |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
Superb explination |
Posted: Fri Sep 01, 2006 6:57 am |
|
|
Thank you Newguy. That was very clear. I am going to hookup an oscilloscope to check the timing. _________________ Thanks
mkr |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri Sep 01, 2006 9:18 am |
|
|
If you use the set_timer() to pre-load the register you are going to have an error in your timing. It takes several clock cycles to set that value so your timer is going to be off everytime it loads that value. This will cause your timer to go over it's 1ms frequency. If there are any interrupts that happen during this event the time will be extended even more. The best way, that I've discovered(in my opinion that is), is to have the timer auto-roll over and simply increment a variable to create the proper delay. You'll need to use a crystal that will give you the proper frequency but it should be more reliable. If you're trying to have an interrupt of 1ms then using a 16 bit timer might not roll over quick enough. You might need to use an 8 bit timer.
Ronald |
|
|
|