Accurate TMR0 clock

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Post Reply
liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

Accurate TMR0 clock

Post by liak » Tue Dec 02, 2008 2:17 pm

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

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Tue Dec 02, 2008 5:13 pm

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.

liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

futher illustration and what about using 2 timers

Post by liak » Fri Dec 05, 2008 4:08 am

Dear Doj,
Thanks for the reply. It does clear my understanding a bit. But still I am not sure
The reload count is the number of cycles the PIC needs to reset the timer to its start.
I am still a bit confused about this. Correct me if I am wrong. This is what I understand by your statement:

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

Doj
Posts: 362
Joined: Wed Apr 11, 2007 10:18 pm
Location: East Sussex

Post by Doj » Fri Dec 05, 2008 4:11 pm

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!

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Sun Dec 07, 2008 12:55 am

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:

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
62500us x 16 = 1000000us = 1 second
Last edited by xor on Sun Dec 07, 2008 6:36 am, edited 1 time in total.

liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

Post by liak » Sun Dec 07, 2008 5:24 am

Dear Xor,

Many many thanks for the rescue! :) :D :o
Will go through in detail what you have said earlier. Very useful.

Regards,
Liak

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Sun Dec 07, 2008 6:32 am

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

liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

Post by liak » Mon Dec 08, 2008 5:34 am

Dear Xor and all,
I have encounter a problem in forcing the definition of the variable into data type WORD.

Code: Select all

Dim CCPR as CCPR1L AsWord 
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:

Code: Select all

dim Timer1 as word(TMR1L) 
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

liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

Post by liak » Mon Dec 08, 2008 5:57 am

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:

Code: Select all

Dim Test As TMR1L.AsWord
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.

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Mon Dec 08, 2008 2:00 pm

Sorry, I didn't use the compiler to write the code and check the syntax. Like all code writing you sometimes find yourself working through the silly syntax errors.

liak
Registered User
Registered User
Posts: 195
Joined: Fri Oct 05, 2007 12:26 am

Post by liak » Mon Dec 08, 2008 11:00 pm

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. :idea:

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. :wink:

Regards,
Liak

Post Reply