I wrote:
> >
> >The solution is to pick your crystal frequency and your prescaler value
> >such that you never write to the rtcc. It should be allowed to overflow.
> >This way, the prescaler is never cleared to zero and no clock ticks are
> >lost.
> >
Mike Keitz wrote:
{Quote hidden}> This is a solution. Here are some others:
>
> * Don't use the prescaler at all. Problem with this is that the interrupt
> rate will be rather fast.
>
> * If using the internal clock to drive the prescaler, then the prescaler
> value is *known* at all times in the interrupt routine, as it continues to
> run. Jerry alludes to this in his description above. If the prescaler is
> set to 16 for instance, about 16 instructions into the interrupt routine it
> will count around to 0 again. (probably 15 or less since launching the
> interrupt uses some cycles). Writing the RTCC at that point would still
> reset the prescaler, but this wouldn't cause a timing error as it is already
> 0. (There is also the issue of the poorly-documented "2-cycle
> synchronization delay". Is this also reset?) In any case, my point is that
> when using internal clocks, the timing error resulting from writing to the
> RTCC during an interrupt routine will be constant, although possibly hard to
> figure out exactly. This is also a way to get "fractional" resolution of
> the interrupt rate without having to "jitter" the reload count. But there
> may be a long wait if a large prescale value is used.
>
> * The 12-bit PICs (16C5X) have a similar RTCC, but no interrupt capability.
> Timing on them is done by polling the RTCC. In this case, writing to RTCC
> is the last resort, since it is hard (not impossible) to determine the
> contents of the prescaler. One of the digital clock app notes from
> Microchip made the mistake of writing, they probably didn't test it over a
> long enough time to see that it didn't work. One way to trigger an action
> every "n" (n < 256) RTCC counts is to read and compare with an expected value:
>
> wt4rtcc
> movfw RTCC ;Get RTCC value
> xorwf exprtcc,0 ;Compare to expected value
> skpz ;Skip if expected value reached
> goto wt4rtcc ;Keep looping until value reached.
> movlw n ;Number of RTCC counts required till next time
.
> addwf exprtcc,1 ;Update the expected value for next time.
>
> The code below this routine will then execute 7 to 12 cycles after RTCC
> reaches the expected value. The prescaler must be set to 8 or more if using
> the internal clock option, if externally clocked the RTCC must not increment
> faster than once every 5 instruction cycles. Great simplification is
> possible if n=256, if n is a power of 2, the general routine above could
> also be simplified.
>
Thank you Mike,
I like these solutions and in fact have added them to my PIC notes file.
It can be difficult however to analyze the system to come up with accurate
timing when messing with the RTCC. For example, If you have anything but a
very simple interrupt routine that may make several decisions and make any
number of jumps that may or may not involve two cycle instructions then you
will have to analyze every possible path and compensate for time lost in the
prescaler.
I just chose a simple solution to minimize my own effort. My own lazyness
has resulted in many elegant yet simple soulutions :).
For example, for a clock, I would go with a 4194304 crystal (common freq),
and set the prescaler to 16. Then I would let the RTCC overflow and never
write to it. This will result in 256 interrupts a second. Use a software
variable as a counter and everytime this counter reaches zero voila, 1
second.
4194304/4/16/256/256=1
With the prescaler set to 16 along with the RTCC counter, this will give you
4096 instructions to play with between each interrupt. For a clock, this
should be plenty.
If you need ms resolution go with a 8192000 (also common) crystal and a
prescaler value of 8.
8192000/4/8/256=1000
This will result in a 1ms interrupt.
If however you are turning your real time clock on and off, and need lots of
processing between interrupts, a more thorough analysis of timing should be
done and a method similar to the ones Mike suggested above should be used.
Very interesting discussion. Thanks!
Jerry