Searching \ for '[PIC] 18F secondary oscillator' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page:
Search entire site for: '18F secondary oscillator'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] 18F secondary oscillator'
2012\05\28@223942 by PICdude

Hi all,

I've used the secondary osc (with 32.768khz crystals) on 16F's for  some time now, and all's great.  Now, I'm doing this with an 18F23K22,  and it seems to be moving faster than actual -- 10 secs in an hour,  compared to the stopwatch on my phone.  Now to figure out why...

I was using assembly previous, but now on the 18F, I'm doing this in C.

I remember the 16F's had some "quirk" where writing to the TMR1  registers would pause the writing for a couple clock cycles, so I used  to write to only TMR1H, and it did not affect the count.  This is  because I need 0.5 second interrupts (to flash a clock colon).  But if  this were an issue, it would *slow* the clock, rather than make it  faster.

Am I missing anything for the 18F?  I haven't found any such thing in  the datasheet or errata.

Would appreciate some additional eyes to see if I'm doing something  odd here in code.  If not, I'll have to suspect the crystal (though  I've used 100+ of these ECS SMD crystals before {with 22pf caps}, so I  trust them).  This is my code (C18 compiler)...


T1CON = 0b10001101;        // Enable secondary oscillator, 1:1 prescale, no sync..
T1GCON = 0b00000000;        // No gating.
PIE1bits.TMR1IE = 1;        // Enable timer-1 interrupts (1 Hz)


if (PIR1bits.TMR1IF)                // Timer-1 interrupt occurred?
       TMR1H = 0xC0;                // Skip ahead so 2-Hz pulses

       Colon++;                // Toggle colon
       if (Colon == 2)
               Colon = 0;

               // Count time...
               if (Seconds == 60)
                       Seconds = 0;
                       if (Minutes == 60)
                               Minutes = 0;
                               if (Hours == 24)
                                       Hours = 0;
       Flagbits.F_ClockUpdate = 1;        // Display update required
       PIR1bits.TMR1IF = 0;
}        // Timer-1 interrupt

2012\05\28@233024 by IVP

face picon face
> 10 secs in an hour, compared to the stopwatch on my phone

Can you trust your phone ?

Your ISR doesn't indicate anything that would cause such a large
error, as far as jitter or  latency is concerned anyway. 1/360 error
is an odd sort of number for hex registers. If it was 14s (ie 1/256)
then you might suspect a consistent high byte anomaly, for example
the TMR1H loading. The datasheet recommends stopping the timer
if it's asynchronous with the main ocillator before writing. Perhaps
try that, with compensation for jitter, and see if that improves the
accuracy, then look at the best solution. Possibly there's a timing
mismatch between the s/w and the h/w, although if the main oscillator
is running much faster than 32kHz that shouldn't be a problem


'[PIC] 18F secondary oscillator'
2012\06\04@211624 by Neil
Also verified on a bad-ass-looking Citizen watch, which cost me over $10, so it has to be right.

How does one stop the oscillator and maintain accurate timing?  The main oscillator is the internal osc at 32 Mhz, and the secondary 32.768 khz osc is NOT synchronized to the main.

Either way, after a bunch more testing, I found some interesting data...
(a) with the PIC sleeping, timing seems to be accurate
(b) when the timing goes off, it's not consistent -- seems to jump ahead a second or two rather quickly
(c) if I remove the TMR1H reload, timing is correct in sleep or wake.

My guess (just a guess) is that because of some other interrupt being serviced when the TMR1H interrupt occurs, TMR1L may be about to overflow and update TMR1H when the code is updating it too, resulting in some type of "conflict".  I say "conflict" as if it were just that the overflow and subsequent TMR1H increment occurs before the code changing TMR1H, then a bit of time would be lost.

To test my assumption, I'm thinking I could probably wait in a loop (ugh! -- I hate that in interrupts) until TMR1L is some low value, and then re-load TMR1H.  I'd also have to check for TMR1H already being incremented (by a TMR1L overflow), and compensate for that.  I vaguely remember some discussion of this for older 16F chips, but not coming up with much right now.  Will search better when I have a better internet connection.


On 5/28/2012 11:29 PM, IVP wrote:
{Quote hidden}

> Joe

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