Accurate TMR0 clock
Moderators: David Barker, Jerry Messina
Accurate TMR0 clock
Dear all,
I am trying to use TMR0 to generate a clock pulse at every 1 second, as accurate as possible. I have seen the PicMulticalc by MisterE. A few questions I would like to ask:
1. In MisterE's PicMulticalc Timer segment, what does the reload / instruction cycle means?
2. I would have to make the clock as accurate as possible. Anyone has any idea how accurate this can be?
Regards,
Liak
I am trying to use TMR0 to generate a clock pulse at every 1 second, as accurate as possible. I have seen the PicMulticalc by MisterE. A few questions I would like to ask:
1. In MisterE's PicMulticalc Timer segment, what does the reload / instruction cycle means?
2. I would have to make the clock as accurate as possible. Anyone has any idea how accurate this can be?
Regards,
Liak
The accuracy is down to the crystal or other timing source.
The PIC timers are just counting pulses and will always do it accurately.
The reload count is the number of cycles the PIC needs to reset the timer to its start.
If your count for one second is 1000 and the reload is 5 then 1000-5=995.
When your count hits 995 you make the reset take place and the next timing cycle will start in 5 steps(1000 in total) which will keep it accurate.
With a 1 second period even using the internal clock uncalibrated at 2% you will get 998ms to 1002ms in your second.
With crystals it will be closer than you are likely to be able to measure second on second.
The PIC timers are just counting pulses and will always do it accurately.
The reload count is the number of cycles the PIC needs to reset the timer to its start.
If your count for one second is 1000 and the reload is 5 then 1000-5=995.
When your count hits 995 you make the reset take place and the next timing cycle will start in 5 steps(1000 in total) which will keep it accurate.
With a 1 second period even using the internal clock uncalibrated at 2% you will get 998ms to 1002ms in your second.
With crystals it will be closer than you are likely to be able to measure second on second.
futher illustration and what about using 2 timers
Dear Doj,
Thanks for the reply. It does clear my understanding a bit. But still I am not sure
On reaching the count of 995 (in your example), the PIC will reset the TMR0 5 times (which takes 5 instruction cycles) and then resume with the new count of 0, making the total count elapsed = 995 + 5 = 1000. Is that right? But then this raises some more questions to me:
1. Why do we need to reset the TMR0 5 times if once will do the work?
2. What is the purpose of this?
3. How to run this in SF coding? I am currently using the TMR0 module contributed by Darryl Quinn in the wiki. I don't see anyway to add the reload count in it. It is not set as an option.
Further question, my friend. If I am to use another timer let's say timer2 to run the multiplexing of my 7 segment LED display. Theoretically, I think I can do that. The two timers are indeed independant. But will there be conflict in the interrupts of using the two timers together ie TMR0 and TMR2? How to avoid the conflict between the two?
Thanks.
Liak
Thanks for the reply. It does clear my understanding a bit. But still I am not sure
I am still a bit confused about this. Correct me if I am wrong. This is what I understand by your statement:The reload count is the number of cycles the PIC needs to reset the timer to its start.
On reaching the count of 995 (in your example), the PIC will reset the TMR0 5 times (which takes 5 instruction cycles) and then resume with the new count of 0, making the total count elapsed = 995 + 5 = 1000. Is that right? But then this raises some more questions to me:
1. Why do we need to reset the TMR0 5 times if once will do the work?
2. What is the purpose of this?
3. How to run this in SF coding? I am currently using the TMR0 module contributed by Darryl Quinn in the wiki. I don't see anyway to add the reload count in it. It is not set as an option.
Further question, my friend. If I am to use another timer let's say timer2 to run the multiplexing of my 7 segment LED display. Theoretically, I think I can do that. The two timers are indeed independant. But will there be conflict in the interrupts of using the two timers together ie TMR0 and TMR2? How to avoid the conflict between the two?
Thanks.
Liak
Hello liak,
You misunderstand the reload time.
Reload cycles are the number of clock cycles the PIC uses to perform its register reseting, it is nothing to do with SF it is hardware inside the PIC.
I do not know how many cycles it would actually take to reload the timers but it will tell you in the data sheet for your PIC, it may be hard to find but it is there.
I use a module that is posted here:- http://www.sfcompiler.co.uk/wiki/pmwiki ... 3Interrupt
It is code I wrote to understand how interrupts work and shows the reload being taken into account in the comments.
You can have two interrupts running if you wish, one high priority and one low priority but this might be hard work for your first attempt.
I only use one interrupt which is 1 millisecond and then use as many variables as timers as I need.
For 1 second I count 1000.
For 100ms I count 100 etc.
An interrupt is nowhere near as complicated as you might think.
It is simply a piece of code that is run every interrupt period regardless of where your own code is at the time, it jumps to the interrupt code(or vector, service routine) does what youe have written then goes back exactly to the point it left.
It is like a GOSUB which is automatically called every interrupt period.
When the idea hits you it is very simple!
You misunderstand the reload time.
Reload cycles are the number of clock cycles the PIC uses to perform its register reseting, it is nothing to do with SF it is hardware inside the PIC.
I do not know how many cycles it would actually take to reload the timers but it will tell you in the data sheet for your PIC, it may be hard to find but it is there.
I use a module that is posted here:- http://www.sfcompiler.co.uk/wiki/pmwiki ... 3Interrupt
It is code I wrote to understand how interrupts work and shows the reload being taken into account in the comments.
You can have two interrupts running if you wish, one high priority and one low priority but this might be hard work for your first attempt.
I only use one interrupt which is 1 millisecond and then use as many variables as timers as I need.
For 1 second I count 1000.
For 100ms I count 100 etc.
An interrupt is nowhere near as complicated as you might think.
It is simply a piece of code that is run every interrupt period regardless of where your own code is at the time, it jumps to the interrupt code(or vector, service routine) does what youe have written then goes back exactly to the point it left.
It is like a GOSUB which is automatically called every interrupt period.
When the idea hits you it is very simple!
No timer reload is required when using the Compare method of the CCP module. Timer1 is never stopped which maintains accuracy.
1. Setup CCP1CON for Compare with Software Interrupt.
2. Setup T1CON for Timer1 @ 1us increments.
3. Clear Timer1
3. Load CCP1RL:CCPR1H = 62500
4. Start Timer1
5. Enable GIE, PEIE, and CCP1 Interrupt Enables
6. Clear CCP1 Interrupt Flag
7. Increment a Mod16 counter inside your ISR...
8. Clear CCP1 Interrupt Flag in the ISR
One Second occurs on the MOD16 counter rollover:
62500us x 16 = 1000000us = 1 second
1. Setup CCP1CON for Compare with Software Interrupt.
2. Setup T1CON for Timer1 @ 1us increments.
3. Clear Timer1
3. Load CCP1RL:CCPR1H = 62500
4. Start Timer1
5. Enable GIE, PEIE, and CCP1 Interrupt Enables
6. Clear CCP1 Interrupt Flag
7. Increment a Mod16 counter inside your ISR...
8. Clear CCP1 Interrupt Flag in the ISR
One Second occurs on the MOD16 counter rollover:
Code: Select all
Dim Mod16Ctr as Byte
Dim OneSecond as Boolean
Dim CCPR as CCPR1L AsWord
Interrupt Mod16Timer()
Inc(Mod16Ctr)
If (Mod16Ctr And 15) = 0 Then
OneSecond = TRUE
EndIf
CCPR = CCPR + 62500
PIR1.CCP1IF = 0
End Interrupt
Last edited by xor on Sun Dec 07, 2008 6:36 am, edited 1 time in total.
I forgot some code inside the ISR and made a change in the above posted code. You would need to add this code:
Code: Select all
Dim CCPR as CCPR1L AsWord
// add this to the ISR code...
CCPR = CCPR + 62500
Dear Xor and all,
I have encounter a problem in forcing the definition of the variable into data type WORD.
The line above generates syntax error in SF. I encounter similar error also when tried running a segment from David himself. His line looks like this:
This line is taken from the SF help on interrupt. What I understand is to force aliasing Timer1 to TMR1L in the data type WORD. But SF doesn't take this. Can anyone comment or find a way to go around it?
Thanks,
Liak
I have encounter a problem in forcing the definition of the variable into data type WORD.
Code: Select all
Dim CCPR as CCPR1L AsWord
Code: Select all
dim Timer1 as word(TMR1L)
Thanks,
Liak
Dear all,
Seems like I am answering myself. I just went through some materials on Spency's PIC homepage (lots of good stuff there, and he uses SF also!). BTW is Spency someone here on the forum? He should be judging from his proficiency of SF. Anyway, the correct syntax for the lines that I had trouble is:
That is, the "dot" was missed out in Xor's.
But how to correct David's format I have no idea. Maybe David will have to show it.
Regards,
Liak.
Seems like I am answering myself. I just went through some materials on Spency's PIC homepage (lots of good stuff there, and he uses SF also!). BTW is Spency someone here on the forum? He should be judging from his proficiency of SF. Anyway, the correct syntax for the lines that I had trouble is:
Code: Select all
Dim Test As TMR1L.AsWord
But how to correct David's format I have no idea. Maybe David will have to show it.
Regards,
Liak.
Dear Xor and Gramo,
Xor, no harm's done. I should say thanks for helping me all the while. I just posted it to anyone who maybe running the code in the future.
I understand the timer well enough now.
BTW, after checking through the Spency's site, I found out it's Gramo who is maintaining the site.Great job Gramo! I like your site very much, very informative and useful. Keep it up.
Regards,
Liak
Xor, no harm's done. I should say thanks for helping me all the while. I just posted it to anyone who maybe running the code in the future.
I understand the timer well enough now.
BTW, after checking through the Spency's site, I found out it's Gramo who is maintaining the site.Great job Gramo! I like your site very much, very informative and useful. Keep it up.
Regards,
Liak