Searching \ for '[PIC]: Clock Tuning' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/time.htm?key=clock
Search entire site for: 'Clock Tuning'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Clock Tuning'
2001\03\06@234249 by James Cameron

flavicon
face
G'day,

Looking for archived discussions or sample code to adjust for consistent
drift in my PIC 16F877's 4MHz crystal oscillator.  I've tried a few
glances at http://www.piclist.com/ but drew a blank.  Perhaps I know the
wrong keywords.

The problem is that my clock is losing one second every three hours.  It
is at least consistently doing this.  It is well within specifications
for the crystal.  I recall a method mentioned a year or two ago (Paul
Webster perhaps?) that makes minor adjustments to the clock over long
periods by calculating how much change is made each time the user sets
the clock again.  It effectively fixes the problem.  Pointers?

--
James Cameron    spam_OUTquozlTakeThisOuTspamus.netrek.org     http://quozl.netrek.org/

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam@spam@mitvma.mit.edu with SET PICList DIGEST in the body


2001\03\07@080454 by Joe

flavicon
face
Just use a standard crystal for your oscillator and use an adjustable cap
for 1 of the load caps.
A good quality frequency counter will help a lot here.  Also if your not
using a good clock to verify the pic's clock this could add to the problem.
I work at a radio station and we use a Leitch clock to maintain accurate
time.  It dials out for updates periodically and corrects in milliseconds.
My $2,000 laptop's clock is not as accurate as the one you mentioned here
(one second every three hours), although my $20 Timex wrist watch is almost
perfectly accurate (it gains a second about every 3 weeks).  Hope this
helps,

Joe

visit my page - http://www.crosswinds.net/~joeh100
e-mail me @  - joeh100spamKILLspamcrosswinds.net

{Original Message removed}

2001\03\07@115240 by Dan Michaels

flavicon
face
James Cameron wrote:

>Looking for archived discussions or sample code to adjust for consistent
>drift in my PIC 16F877's 4MHz crystal oscillator.
.......
>
>The problem is that my clock is losing one second every three hours.  It
>is at least consistently doing this.  It is well within specifications
>for the crystal.


Your error is ~1/3600, while xtal error is <= 50/1000000 = 1/20000,
so the problem is no doubt in your code. 4 mhz is not an even power
of 2, so your method of adjusting for timer overflows probably needs
to be fixed. Look there.

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam.....mitvma.mit.edu


2001\03\07@143846 by Dan Michaels

flavicon
face
I wrote:
>.......
>>The problem is that my clock is losing one second every three hours.  It
>>is at least consistently doing this.  It is well within specifications
>>for the crystal.
>
>
>Your error is ~1/3600, while xtal error is <= 50/1000000 = 1/20000,
>so the problem is no doubt in your code. 4 mhz is not an even power
>of 2, so your method of adjusting for timer overflows probably needs
>to be fixed. Look there.
>

Ooops, 1sec/3hours = ~1/10000, so if you are using a +/-100 ppm
xtal, then it could be your problem.

If you look around, you can find 4Mhz xtals with 30 ppm - like
Epson CA-301 [avail Digikey]. This would give you 1sec/9 hours,
if s.w. is ok.

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspam_OUTspamTakeThisOuTmitvma.mit.edu


2001\03\07@173223 by Jake Tweenie

flavicon
face
Hi Joe
read
http://www.piclist.com/techref/clocks.htm
where it says  Jim hartman says:-

My code at tmr0 roll over

tmr0int  movf    tf0,w
         addwf   prod0,f

         movf    tf1,w
         btfsc   STATUS,C
          incfsz tf1,w
           addwf prod1,f

         movf    tf2,w
         btfsc   STATUS,C
          incfsz tf2,w
           addwf prod2,f
 movf    tf3,w
      btfsc   STATUS,C
        incfsz tf3,w
         addwf prod3,f

 nop
 btfss prod3,7        ;is bit 31 set
 goto notsec           ;no
 bcf prod3,7           ;yes bit 7 prod 2 = fraction bit 31 now clear
 bsf Flags,3             ; set the 1 second flag
 incf Seconds,f            ; for now have sec counting forever 0 to 255
notsec  bsf Flags,2             ; set 32.768 msec flag come here if not
second up
 bcf INTCON,T0IF          ; end of int
 goto POP   ;restore registers and return from interupt

at reset start of code
movlw 0x3E  ;set literal into tf0-3 31 bits = 0x0431BD
movwf tf0
movlw 0x6D
movwf tf1
movlw 0x0C
movwf tf2
movlw 0x01
movwf tf3

this is for pre scale /32

I have a spread sheet for tweaking the fraction for the xtal on a so many
seconds per day calibration,

What I am going to do is try to get the clock self calibrating
this is I think the way to go
paul
paulspamspam_OUTg4bks.fsnet.co.uk
please reply to this email

{Original Message removed}

2001\03\07@224327 by Roman Black

flavicon
face
Dan Michaels wrote:
>
> James Cameron wrote:
>
> >Looking for archived discussions or sample code to adjust for consistent
> >drift in my PIC 16F877's 4MHz crystal oscillator.
> .......
> >
> >The problem is that my clock is losing one second every three hours.  It
> >is at least consistently doing this.  It is well within specifications
> >for the crystal.
>
> Your error is ~1/3600, while xtal error is <= 50/1000000 = 1/20000,

Unless it's a resonator?? :o)
-Roman

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-requestKILLspamspammitvma.mit.edu


2001\03\07@232507 by James Cameron

flavicon
face
On Wed, Mar 07, 2001 at 11:52:40AM -0500, Dan Michaels wrote:
> James Cameron wrote:
> >Looking for archived discussions or sample code to adjust for consistent
> >drift in my PIC 16F877's 4MHz crystal oscillator.
> .......
> >The problem is that my clock is losing one second every three hours.  It
> >is at least consistently doing this.  It is well within specifications
> >for the crystal.
> Your error is ~1/3600, while xtal error is <= 50/1000000 = 1/20000,
> so the problem is no doubt in your code. 4 mhz is not an even power
> of 2, so your method of adjusting for timer overflows probably needs
> to be fixed. Look there.

Ah, maybe I've got one of those off-by-one problems.  I checked most
carefully ... TMR0 at 1:256, should give one T0IF every 65536uS exactly,
which I add into a 24-bit counter and then subtract one second.  If the
result is positive, I keep the new counter value and activate my 1Hz
code path.  TMR0 runs free, never reset.  Does this logic seem sound?

http://quozl.netrek.org/uptime/uptime.asm is the code.
http://quozl.netrek.org/uptime/ has the rest of the code.

--
James Cameron    KILLspamquozlKILLspamspamus.netrek.org     http://quozl.netrek.org/

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu


2001\03\08@004445 by myke predko

flavicon
face
Hi James,

The only thing that I wasn't sure about was the lines:

;; subtract 1s from copy of counter
movlw d'1000000'&0xff
subwf t0,f
btfss status,c
decf t1,f

This is an eight bit subtract of a 24 bit value, but you are not bringing
the carry to the most significant byte ("t2").  I haven't done any kind of
analysis on what this can do to you, but I'm sure every once in a while it
will bite you.

I would suggest something like:

;; subtract 1s from copy of counter
movlw d'1000000'&0xff
subwf t0,f
btfsc status,c
 goto $ + 5  ;; If No Borrow, Subtract from the Middle Byte
movlw d'1'
subwf t1,f
btfss status,c
 decf t2,f ;;  "t1" was Zero upon Entry into Subtraction Routine, Decrement
t2

myke



{Original Message removed}

2001\03\08@010627 by Dan Michaels

flavicon
face
James Cameron wrote:
{Quote hidden}

James, in case you didn't see it, I posted a later msg indicating
your actual error is ~1/10000 [I overlooked the "3" the first time
--> sorry], which could correspond to about 100 ppm, or a typical xtal
operating on the edge.

However, when you're using a xtal which is not an even power of 2,
you always run the risk of the off-by-one problem, as you indicated,
so you really have to scrutinize your code. I downloaded your ASM file,
but couldn't really read it as it formatted funny in my editor.

If timing is really critical, as other possible options, I would
suggest using a xtal like 4.096 Mhz, which makes the code more
straightforward, and finding one with 20-30 ppm characteristics.

After everything else is beaten to a pulp, you can always try
the tunable cap in the xtal ckt.

- dan

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@012140 by Scott Dattalo

face
flavicon
face
On Thu, 8 Mar 2001, myke predko wrote:

{Quote hidden}

If you wanna do this why not do it like:

 clrf  FSR   ;) Intentional obfuscation
 movlw d'1000000'&0xff
 subwf t0,f
 RLF   FSR,w
 subwf t1,f
 RLF   FSR,w
 subwf t2,f

If FSR is always 0, then the clear only needs to be done once.

another variation:

 movlw d'1000000'&0xff
 subwf t0,f
 movlw 1
 skpnc
  subwf t1,f
 skpnc
  subwf t2,f

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@022909 by Vasile Surducan

flavicon
face
On Wed, 7 Mar 2001, Dan Michaels wrote:

> I wrote:
> >.......
> >>The problem is that my clock is losing one second every three hours.  It
> >>is at least consistently doing this.  It is well within specifications
> >>for the crystal.
> >
> >
> >Your error is ~1/3600, while xtal error is <= 50/1000000 = 1/20000,
> >so the problem is no doubt in your code. 4 mhz is not an even power
> >of 2, so your method of adjusting for timer overflows probably needs
> >to be fixed. Look there.
> >
>
> Ooops, 1sec/3hours = ~1/10000, so if you are using a +/-100 ppm
> xtal, then it could be your problem.
>
> If you look around, you can find 4Mhz xtals with 30 ppm - like
> Epson CA-301 [avail Digikey]. This would give you 1sec/9 hours,
> if s.w. is ok.

 You may find quiqly that, using a periodmeter and measure the second
outputed to a pic pin or a frequencymeter connected directly to osc-out.
Input impedance must be about 1M/20pF. Frequency drift is visible.
Vasile

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@090554 by Olin Lathrop

face picon face
> Ah, maybe I've got one of those off-by-one problems.  I checked most
> carefully ... TMR0 at 1:256, should give one T0IF every 65536uS exactly,
> which I add into a 24-bit counter and then subtract one second.  If the
> result is positive, I keep the new counter value and activate my 1Hz
> code path.  TMR0 runs free, never reset.  Does this logic seem sound?

Seems reasonable enough, although there could still be a bug in the
implementation.  Someone else pointed out that your error is right at the
edge of what the crystal may be rated at, so maybe your code is fine.

Back to your original question about how to make minor adjustments to
account for crystal error.  Your algorithm provides an obvious way to do
this.  You count elapsed uS in chunks of 65536 derived from timer 0
overflows, then subtract out exactly 1,000,000 uS every second.  All you
have to do is modify this 1,000,000 number slightly to account for the
number of ticks you actually get in one second.  For example, if you clock
runs 1 second fast in 3 hours, then you really have 1,000,093 ticks in a
second.


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, spamBeGoneolinspamBeGonespamembedinc.com, http://www.embedinc.com

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@150133 by Andrew Warren

flavicon
face
myke predko wrote:

> This is an eight bit subtract of a 24 bit value, but you are not
> bringing the carry to the most significant byte ("t2").

and Scott Dattalo <TakeThisOuTPICLISTEraseMEspamspam_OUTMITVMA.MIT.EDU> replied:

{Quote hidden}

Scott:

After reading the recent "commenting practices" thread that was
sparked by Myke Predko's use, with no explanatory comments, of the
FSR as a generic temporary variable (and worse, if you recall, he
used the temporary variable in ALMOST the same way that the FSR is
usually used), I think I'd rewrite your code like this:

   LIST    P=16C54,R=DEC

   MOVLW   1<<6        ;No need for "&0xff", since 1000000 = 1E6.
   SUBWF   T0,TMR0     ;TMR0 has just overflowed.
   MOVLW   F           ;W register = F (just F, not 0x0F).
   BTFSC   STATUS,W    ;Skip if C (just C, not 0x0C) = W.
   SUBWF   T1,W+1      ;(W register = F still, but W = F-1).
   BTFSC   STATUS,INDF ;We're using INDF and FSR together
   SUBWF   T2,(FSR-3)  ; here, but not in the usual way.

This code assembles identically to yours... But since it's fully
commented, it's clearly better.

-Andy


=== Andrew Warren --- RemoveMEaiwspamTakeThisOuTcypress.com
=== IPD Systems Engineering, CYSD
=== Cypress Semiconductor Corporation
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@153908 by Scott Dattalo

face
flavicon
face
On Thu, 8 Mar 2001, Andrew Warren wrote:

{Quote hidden}

Yes! I love it!

We just HAVE to start the "most obfuscated pic code" (MOPcode) contest in the
same vain of the PERL contests.

Check out the DeCSS Perl code posted on slashdot yesterday
http://www.cs.cmu.edu/~dst/DeCSS/Gallery/qrpff.pl

Scott

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@210615 by Olin Lathrop

face picon face
> Yes! I love it!
>
> We just HAVE to start the "most obfuscated pic code" (MOPcode) contest in
the
> same vain of the PERL contests.

I thought that was what APL was for.


*****************************************************************
Olin Lathrop, embedded systems consultant in Devens Massachusetts
(978) 772-3129, EraseMEolinspamembedinc.com, http://www.embedinc.com

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\08@215429 by Bob Ammerman

picon face
{Quote hidden}

Andy,

It took me a minute or so to realize you were joking. Until then I really
wondered what you were up to!

Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads


2001\03\09@073835 by Peter L. Peres
picon face
> Ah, maybe I've got one of those off-by-one problems.  I checked most
> carefully ... TMR0 at 1:256, should give one T0IF every 65536uS exactly,
> which I add into a 24-bit counter and then subtract one second.  If the
> result is positive, I keep the new counter value and activate my 1Hz
> code path.  TMR0 runs free, never reset.  Does this logic seem sound?

You have a pre-programmed two-second jump at constant intervals in your
code as the remainder keeps growing until it reaches two seconds (exactly)
in the 24 bit accumulator. At that time you will go the 1Hz path twice,
once for each of two successive ticks. One second does not divvy cleanly
by 65536.

1000000/65536 = 15.258789062 ...
15*65536 = 983040
1000000-last = 16960

Wrt. the ellipsis, you need to find out how accurate the divider chain can
be made wrt. the crystal accuracy. It is not accurate now. A hack to make
it more accurate now is to substract an additional 1130 units from the 24
bit counter every time you go to the 1Hz path, and once every 1130 1Hz
paths substract another 10 units from the 24 bit accumulator.

16960/15 = 1130.666666666 ...
1130*15  = 16950

I assume that the 24 bit accumulator stores ticks, not seconds. The trick
could be made more even by substracting 1131 and adding 5 but then I would
have to assume that you also have adder code on 24 bits and I do not
assume that ;-)

In general, the higher the granularity of the clock, the better the
chances to be able to make it more accurate. Therefore, next time, imho
plan to apply the corrections as soon in the divider chain as
technically possible (see also my previous posting on this).

You could have implemented it using a small state machine that changes the
reload value of TMR0 at certain times. You would have gotten away with
mostly cascaded 8-bit counters instead of a 24 bit accumulator.

hope this helps

Peter

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\03\09@073855 by Peter L. Peres

picon face
> that makes minor adjustments to the clock over long periods by
> calculating how much change is made each time the user sets the clock
> again.  It effectively fixes the problem.  Pointers?

Basically you keep an extra counter that counts seconds (or whatevers)
since the last set operation occured and when a new set operation occurs,
the difference (which is what you enter to set the clock), is obtained.
You then have D and T, the time over which it occured. Be sure to use the
same units for D and T. For ex. if D is expressed in seconds and T in TMR0
ticks you need to convert seconds -> ticks. This will imply in error but
you can only do so much.

The simple way is, to divide T by D, obtaining T1 and then arrange for
another counter to count from 0 to T1-1. When reaching T1 add or substract
one time unit from the currently indicated one of the clock.

The more complex way is, to obtain a fraction derived from T and D that
can be used to apply correction more accurate than in the previous
paragraph.

The correct way is to apply the correction in the highest resolution part
of the timer that runs the clock (e.g. TMR0 or whatever) in the form of a
fraction obtained as in the previous paragraph. This prevents abrupt jumps
in time which can be caused by the methods previously shown (and drive
alarm clocks go crazy by making them miss sheduled events).

Just in case you did not get the point about the fraction, a correction
fraction expressed as D/T can be interpreted as 'In every T tick cycles
add or substract D units from the clock'. When applying this to a higher
divider it can become 'In every T/k tick cycles add or substract D/k units
from the clock', where k is chosen as large as possible. In the end, D
will be expressed as a number of TMR0 ticks that should be added or
substracted to the TMR0 over a certain legth of time, T.

This can be 'watered down' to induce the minimum possible disturbance by
making the correction to the master tick one LSB (+/-1 tick in the reload
value), and spread the reloads evenly over the T period.

Do clocks still look simple ? ;-)

hope this helps,

Peter

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2001\03\09@123237 by Andrew Warren

face
flavicon
face
Bob Ammerman <RemoveMEPICLISTEraseMEspamEraseMEMITVMA.MIT.EDU> wrote:

> > LIST    P=16C54,R=DEC
> >
> > MOVLW   1<<6        ;No need for "&0xff", since 1000000 = 1E6.
> > SUBWF   T0,TMR0     ;TMR0 has just overflowed.
> > MOVLW   F           ;W register = F (just F, not 0x0F).
> > BTFSC   STATUS,W    ;Skip if C (just C, not 0x0C) = W.
> > SUBWF   T1,W+1      ;(W register = F still, but W = F-1).
> > BTFSC   STATUS,INDF ;We're using INDF and FSR together
> > SUBWF   T2,(FSR-3)  ; here, but not in the usual way.
> >
> > This code assembles identically to yours... But since it's fully
> > commented, it's clearly better.
>
> It took me a minute or so to realize you were joking. Until then I
> really wondered what you were up to!

Bob:

Joking?  I wasn't joking; it DOES assemble identically to Scott's
code, and every line IS commented.

In fact, this exercise has made me realize that I haven't really been
following good coding practices all these years.  You know how the
computer scientists say that you should assign symbols to constants
and use THEM rather than sprinkling the raw constants through your
code?  I'm going back through all my PIC code and fixing it:

   MOVLW 0    becomes MOVLW W
   ADDLW -1   becomes ADDLW -F
   XORLW 0xFF becomes XORLW W-F
   etc...

-Andy


=== Andrew Warren - RemoveMEfastfwdspam_OUTspamKILLspamix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


More... (looser matching)
- Last day of these posts
- In 2001 , 2002 only
- Today
- New search...