Searching \ for '[PIC]: Clock runs slow ?' 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 runs slow ?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Clock runs slow ?'
2001\10\15@191007 by Peter L. Peres

picon face
Hi,

I made a clock to test a timer routine implemented using Bob Ammermann's
and Roman Black's idea (of accumulator that is substracted from each TMR0
overflow), and the clock runs slow, with a fast crystal. The crystal is
4MHz +60ppm (measured) and the clock loses about 5 seconds in two hours,
which is -700ppm or so. I use psc=0 (div 2) which causes interrupts at
about 1953Hz with 4MHz crystal. The accumulator adds an extra tick every 8
ticks with this scheme (TMR0: /2/256 = Tcyc/512 etc: 1000000/512 1953.125
- where the .125 becomes 1 extra after 8 ticks).

Since until now I did all my clocks using interrupt-less PICs using
constant run time code etc. I need to ask whether there is any known
problem with the PIC that causes this (it's a 16F84 for development),
before I take my code apart again. The timer tick is the only used
interrupt, but all interrupt sources are handled in stubs in the ISR so
stray pulses are excluded. Scoping pins brings no joy (I do PORTB ^= 0x80;
at the end of each TMR0 ISR). I am almost sure that I missed something in
this code but I have to ask...

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\10\16@035303 by Roman Black

flavicon
face
Peter L. Peres wrote:
{Quote hidden}

Peter, I think you may have misunderstood the
system? Why add the extra tick?? The beauty of
the system is that you only need one 24bit number
which is as accurate as timer0 tick.

So, for your example, you have a 4MHz crystal,
1MHz clock, prescaler/2 so timer0 tick is
500,000 to a second (2ppm).

So the system will ALWAYS be accurate to within
2ppm, and since your crystal is only good for
maybe 50ppm at best the software system can't
be a problem. :o)

Have you seen my spuedo code here:
centauri.ezy.net.au/~fastvid/one_sec.htm
-Roman

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\10\16@204815 by Djula Djarmati

flavicon
face
>I made a clock to test a timer routine implemented using Bob Ammermann's
>and Roman Black's idea (of accumulator that is substracted from each TMR0
>overflow), and the clock runs slow, with a fast crystal. The crystal is
>4MHz +60ppm (measured) and the clock loses about 5 seconds in two hours,
>which is -700ppm or so. I use psc=0 (div 2) which causes interrupts at
>about 1953Hz with 4MHz crystal. The accumulator adds an extra tick every 8
>ticks with this scheme (TMR0: /2/256 = Tcyc/512 etc: 1000000/512 1953.125
>- where the .125 becomes 1 extra after 8 ticks).


Peter,

   It's probably the software. A few rules for accurate clock:
- Never modify the TMR0 (unless you know exactly what you're doing). Any
write to TMR0 will clear the prescaler = ticks are lost.
- Be sure that in the worst case the interrupt routine is finished in 512
cycles, othervise you'll lose an interrupt.
- If you disable the interrupts in the main code, don't do it for more than
512 cycles.
- Capacitors at OSC1 and OSC2 can also affect the crystal frequency, you can
use them to fine-tune the clock.


Regards,

Djula

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2001\10\17@170754 by Peter L. Peres

picon face
Hi Roman,

> Peter, I think you may have misunderstood the
> system? Why add the extra tick?? The beauty of
> the system is that you only need one 24bit number
> which is as accurate as timer0 tick.

I don't think that I misunderstood the system. I think I improved it. And
I don't think that the mistake is there. It could be something else. I am
asking because I am looking for new ideas (having run out of my own).

I only need a 16 bit counter because the 24 bit value that expresses
1,000,000 ends in 0x40. (1 mil is 0x0F 0x42 0x40). Then we notice that the
number of ticks to substract is 512 per interrupt, which is 0x200, or 0x02
0x00 in my notation. The substraction leaves the l.s.byte unchanged all
the time, it only needs to be added in when the constant is added at the
unedrflow time (every second).

So I do not use the last byte, the initial counter is 16 bits and loaded
with 0x0F 0x44 (0x44 = 0x40 + 0x200), and I have an auxiliary counter that
is loaded with 8 and decrements every interrupt. When it reaches zero I
add 0x200 to 0x44 which causes the next 'second' to be 512 T cycles
longer, and provides the correction, and is reloaded with 8. The effect is
exactly the same as a 24 bit accumulator where the 0x40 LSB would add up
to 0x200 after 8 additions.

Obviously I compare the accumulator with 0x200 not 0 to detect when the
time has come, as you have pioneered. This is not so usefull in assembly
where one has direct access to the carry flag, but it is essential in
portable ANSI C where one has not (most of the time).

My ISR is very short, and sets a flag that is used and cleared by the main
code. The main code just spins waitong for the flag and checks some keys.
There is no way the ISR could spend 'too much time' and miss an interrupt.
The code is in C but I assume the ISR takes less than 50 T cycles all
together worst case. I will read the code but I do not think that this is
necessary in this case.

I could have used a 24 bit accumulator but I did not need it here, the
code is simpler like this. If I'd use a crystal with a strange frequency
maybe I'd use a proper 24 bit accumulator.

There has to be something that oopses me and I can't find it.

thanks for the ideas,

Peter

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


2001\10\18@031909 by Roman Black

flavicon
face
Peter L. Peres wrote:
>
> Hi Roman,
>
> > Peter, I think you may have misunderstood the
> > system? Why add the extra tick?? The beauty of
> > the system is that you only need one 24bit number
> > which is as accurate as timer0 tick.
>
> I don't think that I misunderstood the system. I think I improved it. And
> I don't think that the mistake is there. It could be something else. I am
> asking because I am looking for new ideas (having run out of my own).
>
> I only need a 16 bit counter because the 24 bit value that expresses
> 1,000,000 ends in 0x40. (1 mil is 0x0F 0x42 0x40). Then we notice that the
> number of ticks to substract is 512 per interrupt, which is 0x200, or 0x02
> 0x00 in my notation. The substraction leaves the l.s.byte unchanged all
> the time, it only needs to be added in when the constant is added at the
> unedrflow time (every second).


I really don't think you improved it at all,
instead of using one 24 bit variable with a
simple subtraction that always self-corrects,
you are using a 16 bit variable and another
8bit variable with manual error checking. Once
you start doing manual error detect and correct
it's no longer a bresenham, it's just clumsy
timer code. :o)

Ok, if you are fixed at the 4MHz crystal,
1MHz inst, and you need 1 second period, why
not set the prescaler to /16, which turns
1,000,000 ticks into 62,500 ticks. This will
fit into a 16bit variable. Then every time
timer0 int occurs, every 244Hz, just subtract
one from the hi byte, giving you a simple
16bit bresenham timer. Then when the 16bit
variable gets below zero add another 62,500
to whatever is left in it and generate your
one second event.

This will be very simple in your 16bit C
library and has the added advantage of using
8x less total interrupt time than your current
system.
-Roman

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


2001\10\18@042644 by jeethur

flavicon
face
Peter,

       I too had exactly the same problem in an 24 Hrs On/Off Timer
       using Roman's code. But the problem was later found to be
       in my TMR0 ISR. I was driving 3 shift registers once in
       every 64 ticks and that was causing one timer interrupt
       to be lost.

       I did'nt have enough time to rewrite the entire
       software for this small problem. So, I calculated the error
       and compensated the 24bit clock speed constant for this error.
       Its been working fine since then. And that was about 2 months back.

Regards,

Jeethu Rao

> {Original Message removed}

2001\10\18@174950 by Peter L. Peres

picon face
Ok, I have solved it. I made a mistake in the decrement vs. reload
sequence of the registers, due to the past midnight hour. This added the
offset that I found (about -700ppm).

thank you for your help,

Peter

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


2001\10\19@161048 by Peter L. Peres

picon face
Hi Roman,

> I really don't think you improved it at all, instead of using one 24
> bit variable with a simple subtraction that always self-corrects, you
> are using a 16 bit variable and another 8bit variable with manual
> error checking. Once you start doing manual error detect and correct
> it's no longer a bresenham, it's just clumsy timer code. :o)

Oook. ;-).

1. I am using 3 byte variables (C unsigned char), not one 24 and not 1 16
+ 1 byte. This is essential for portability. I simulate the code on a PC
so.... My code runs cleanly in 4 different compilers, only one of them a
PIC targeted one.

2. I am really curious as to how accurate your clocks are. I need to get
to 1 sec per month at quasi-constant temperature and I CANNOT twiddle a
trimmer in them, not that it would help. So I use software programmed
correction. In an average month 1 second is equivalent to 0.38 ppm. A $40
TCXO from Mouser (Fox I think) for example will not do that. My
inexpensive (but waterproof) wristwatch is pretty good at this, sice I
never take it off (hint, hint), and only does 10 seconds per month (~4ppm)
after adjustment over some time. Random measurements in various labs show
that most frequency counters that were not of particularly good quality or
recently calibrated were off by +/- 50 Hz (at 10MHz usually), which is
5ppm. The color subcarrier in countries with PAL is specified to +/- 50 Hz
and is usually within +/- 30hz (~0.68 ppm). I think that we beat this
horse dead once already in another thread. This is not a flame, just a
reminder of what is going on here.

> Ok, if you are fixed at the 4MHz crystal,
> 1MHz inst, and you need 1 second period, why
> not set the prescaler to /16, which turns
> 1,000,000 ticks into 62,500 ticks.

By doing this you get:
1000000/4096  <- 4096 = 16*256 = TMR0 overflow with your setting
244.140625000 <- a 'nice' fraction. Not.
1000000-244*4096
576           <- remainder of Tcyc that will be left over.

The /2 prescaler only causes a 512 usec jitter in one of the second
timers, once every 8 seconds. Your /16 divider induces a 4096 usec jitter
in one of 7.(1) seconds which I wish you good luck to predict in your
other code... Also the TMR0 interrupt (~244Hz) becomes too slow for my
other purposes.

> This will be very simple in your 16bit C
> library and has the added advantage of using
> 8x less total interrupt time than your current

My current interrupt code for TMR0 is 11 lines of C using only unsigned
char variables, and 8 bit arithmetic. I don't even use
decrement-in-assignment and other nasty C source compressions.

Peter

PS: The code looks like this:

 /* unoptimized C compiles with many compilers, A0,1,2 are global
  * unsigned chars, prescaler /2 for 4Mhz, /4 for 8MHz etc
  */
 A1 -= 2;
 if(!A1) {
   if(!A2) { /* the time has come (one second) */
     A2 = 0x0F;
     A1 = 0x42;
     A0--;
     if(!A0) {
       A0 = 8;
       A1 += 2;
     }
     Update = 1;
   }
   A2--;
 }

In assembly that would be (untested! I am 'compiling' by brain from
above, with -O1 ;-) ):

;; code optimized by predecrementing A2 which requires reload with 0x10
;; (== 0x0F + 1) and allows all the accumulators to be shifted right by
;; one and decrements of 1 required, instead of 2 to save a few code
;; bytes.

;; In TMR0 interrupt handler, running with psc=/2 Xtal=4MHz. To run with
;; other crystals just scale the prescaler with the Xtal. TMR0 interrupt
;; is ~1953 Hz (1953.125 exactly). 1 mil is 0x0F 0x42 0x40 and the 0x40
;; error adds up to a unit after 8 seconds, causing every 8th second to
;; be 448 usec longer than the others (+448 ppm of that second), while
;; the previous 7 seconds are all 64usec short (-64 ppm for each second).

;; 15 words, worst case runtime 15 T (15/512 ~= 3% load @ 4MHz w/o overh.)
 decfsz  A1,f
 btfss   STATUS,Z
 goto    l1

 decfsz  A2,f    ; ***
 goto    l1

 movlw   0x08    ; 0x10/2 ; 0x10 = 0x0F+1 because of ***
 movwf   A2
 movlw   0x21    ; 0x42/2
 movwf   A1      ; each of seven 999936 usec short seconds

 bsf     Flags,Update ; used and cleared by main

 decfsz  A0      ; every 8th second, one tick 512 Tcyc longer
 goto    l1

 movlw   8
 movwf   A0      ; every 7 short seconds one long one

 incf    A1,f    ; A1 + 1 -> 1000448 usec 8th, long second

l1: ;; 1 sec clock code done

PS2: Sorry for the long post.

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


2001\10\19@161059 by Peter L. Peres

picon face
> I did'nt have enough time to rewrite the entire software for this
> small problem. So, I calculated the error and compensated the 24bit
> clock speed constant for this error. Its been working fine since then.
> And that was about 2 months back.

Oh, exam result fudge ;-) Ok, everyone does it, they just don't talk about
it. <g>

Peter

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


2001\10\20@101814 by Roman Black

flavicon
face
Peter L. Peres wrote:
>
> Hi Roman,
>
> > I really don't think you improved it at all, instead of using one 24
> > bit variable with a simple subtraction that always self-corrects, you
> > are using a 16 bit variable and another 8bit variable with manual
> > error checking. Once you start doing manual error detect and correct
> > it's no longer a bresenham, it's just clumsy timer code. :o)
>
> Oook. ;-).
>
> 1. I am using 3 byte variables (C unsigned char), not one 24 and not 1 16
> + 1 byte. This is essential for portability. I simulate the code on a PC
> so.... My code runs cleanly in 4 different compilers, only one of them a
> PIC targeted one.

Hmm, not having seen your code I can only
guess. The real beauty of the Bresenham
system is that it is ZERO ERROR, ie, the
system corrects itself and only needs
one subtraction per interrupt.

> 2. I am really curious as to how accurate your clocks are.

Thay are as accurate as the cystal being used.
simply because the system has ZERO error, the
clock accuracy can only be affected by total
crystal accuracy.

{Quote hidden}

Ok, so now you mention you need super-accuracy!
This is going to require either a super-accurate
timebase, like a crystal-oven good for <1ppm,
or a system which is time locked to an external
timebase with the desired accuracy (like the
AC mains??).

The software system is not the problem here, you
have entered the realm of super-accurate crystals
and other methods...

{Quote hidden}

No offense Peter, but again seems you don't
quite grasp the benefits of the Bres timer
system?
You don't need to predict anything, the Bres
system keeps perfect time over any given period,
no matter what period, not matter what int
frequency, etc etc. That is its one great
advantage.

Remember Bresenham timer can be used at ANY
int speed as it has ZERO total error. Is a
small percentage of jitter a problem??

> > This will be very simple in your 16bit C
> > library and has the added advantage of using
> > 8x less total interrupt time than your current
>
> My current interrupt code for TMR0 is 11 lines of C using only unsigned
> char variables, and 8 bit arithmetic. I don't even use
> decrement-in-assignment and other nasty C source compressions.

I'm not an expert in PIC C but your code
is pretty straightforward. I don't think
this is a code issue or even a system issue.

What exactly do you want to achieve??
Do you want to get <1ppm error from a PIC
with a "normal" crystal??? If this is the
issue, then your code is not going to be the
weak link...
-Roman

--
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\10\22@163421 by Peter L. Peres

picon face
The clock achieves 0.5ppm after some minor tinkering and burn in. 0.5ppm
is about +/- 1Hz at 4MHz and it can be measured easily. Incidentally the
clock correction factor comes into play into the reload value of what you
call a Bresenham clock. The final algorythm is a little bit different from
what I have posted.

An oven is not required, the clock works at constant temperature and
voltage. Once I replaced the no name 78L05 regulator with a S81350
everything quieted down ...

Peter

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


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