• AVR Freaks

Hot!PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal

Author
ninjabean
New Member
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2014/02/25 16:55:09
  • Location: 0
  • Status: offline
2019/08/01 21:37:41 (permalink)
0

PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal

I am working on a PIC16F15323 and want to do some time-keeping. One of the requirements is to keep time drift down to a minimal over 6 months or a year, and this is where I've come to some roadblocks.
 
Now I'm starting to question how accurate is FOSC/4 relative to the external crystal?
 
My 8MHz external crystal connected to the PIC as an external oscillator has 30PPM Tolerance and 20PPM Stability. This suggests my worst case scenario should only be 50PPM out. However, I am over by almost 100us/second (100PPM) using unreasonable load caps (8pF). When I used reasonable cap values of 20pF the PIC fails to lock to the crystal, and when I used 15pF the time runs over by over 120us. If I remove the load caps I am under by about 15us.
 
I am using Timer1 to keep a 1 seconds count, and the clock source is FOSC/4, prescaler is 1:4. System clock is based off the 8MHz crystal/8 = 1MHz.
 
The only interrupt routine I have is Timer1. The content is very light, there are increments and if statement for keeping time up to 24 hours, and I toggle a debug pin.
 
Crystal Specs Link: https://www.digikey.com/product-detail/en/kyocera-international-inc-electronic-components/CX5032GB08000H0HPQZ1/1253-1373-1-ND/4896463
 
Does anyone have any suggestions on how I can improve the timing accuracy using this crystal?
And is it fine to have very low load cap values or even no load caps across the crystal?
#1

12 Replies Related Threads

    Jim Nickerson
    User 452
    • Total Posts : 6185
    • Reward points : 0
    • Joined: 2003/11/07 12:35:10
    • Location: San Diego, CA
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/02 10:07:56 (permalink)
    0
    ninjabean
     One of the requirements is to keep time drift down to a minimal over 6 months or a year
     
     
     

    "minimal" is a nebulous amount, maybe you can state it in seconds ?
    #2
    1and0
    Access is Denied
    • Total Posts : 9610
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/02 10:22:51 (permalink)
    0
    Sound like you got a lot of stray capacitance.  Anyway, clock Timer1 with a clock crystal of 32.768 kHz.
    #3
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11286
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/02 11:01:05 (permalink)
    +1 (1)
    Show your interrupt handler.
    #4
    ninjabean
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2014/02/25 16:55:09
    • Location: 0
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 14:59:52 (permalink)
    0
    1and0
    Sound like you got a lot of stray capacitance.  Anyway, clock Timer1 with a clock crystal of 32.768 kHz.


    The datasheet says "The PIC16(L)F15313/23 devices do not have a secondary oscillator" and my only option is to use FOC/4.
    Space on the PCB is very tight so the crystal layout is not ideal, stray capacitance is probably a bit high but surely it wouldn't be in the 10 to 20 pF range.
    Also, Cstray should be consistent across all boards so do I need to fix this? 
    #5
    ninjabean
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2014/02/25 16:55:09
    • Location: 0
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 15:01:14 (permalink)
    0
    jtemples
    Show your interrupt handler.


     
    Timer0 is only turned on for a few seconds when the user interacts with the system and then turned off. The user is only expected to interact with the system on setup.

    void interrupt INTERRUPT_InterruptManager (void)
    {
        // interrupt handler
        if(PIE0bits.TMR0IE == 1 && PIR0bits.TMR0IF == 1)
        {
            TMR0_ISR();
            LEDFlashFlag = true;
            //Debug_Toggle();
        }
        if(INTCONbits.PEIE == 1)
        {
            if(PIE4bits.TMR1IE == 1 && PIR4bits.TMR1IF == 1)
            {
                TMR1_ISR();
                flagCounter++; // Timers second counter
                SecondCounter++; // RTC runs independent of Timer counter
    #ifdef DEBUG_EN
                MinuteCounter++; // TEST
                Debug2_Toggle();
    #endif
                // Basic Daily RTC
                if (SecondCounter >= 60) // 60s
                {
                    SecondCounter = 0;
                    MinuteCounter++;
                    if (MinuteCounter >= 60){
                        MinuteCounter = 0;
                        HourCounter++;
                    }
                    if (HourCounter >= 24){
                        HourCounter = 0;
                        DailyResetFlag = true;
                    }
                }

            }
            else
            {
                //Unhandled Interrupt
            }
        }
        else
        {
            //Unhandled Interrupt
        }
    }
    /**
     End of File
    */

    post edited by ninjabean - 2019/08/04 15:04:01
    #6
    ninjabean
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2014/02/25 16:55:09
    • Location: 0
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 15:11:02 (permalink)
    0
    JANickerson
    "minimal" is a nebulous amount, maybe you can state it in seconds ?


    Anything under 40PPM would be good enough. i.e. 20 minutes a year or 40us per second.
    #7
    ric
    Super Member
    • Total Posts : 23555
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 15:25:39 (permalink)
    +1 (1)
    The bit of the interrupt handler that jtemples wanted to see is where the timer is being reloaded to get an exact one second interrupt.
    You didn't mention you are using MCC, and you have not shown the code in  TMR1_ISR() which is presumably where the important bit is happening.
    To get an accurate count, it's better to get the hardware to do the reload.
    That would involve using the CCP module with timer 1, or using TMR2 with the programmable reload register to generate exact intervals (usually shorter than a second, but you can just count them to get seconds.)

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #8
    dan1138
    Super Member
    • Total Posts : 3190
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 16:32:30 (permalink)
    0
    @ninjabean,
    Sounds like you are already apologizing for doing a bad PCB layout for the crystal oscillator circuit. There are only bad choices in firmware for fixing crap hardware.

    To do time keeping validate that the oscillation amplifier works as expected.
    • Hold your circuit at a constant temperature of 25°C, ±1°C.
    • Measure that the oscillation is on frequency ±5ppm over the required variation of the VDD voltage.
    • Verify the oscillation amplifier starts at VDD min and VDD max.
    When you can achieve this your circuit will meet your stated needs.
    post edited by dan1138 - 2019/08/06 12:35:51
    #9
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11286
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/04 17:08:29 (permalink)
    +1 (1)
    you have not shown the code in  TMR1_ISR()

     
    I don't use MCC; is this a macro?  Or is it a function with call/return overhead?  If the latter, does the MCC code compensate for that overhead?  Another reason not to use TMR1 in this fashion.
    #10
    NKurzman
    A Guy on the Net
    • Total Posts : 17709
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/05 14:24:22 (permalink)
    +2 (2)
    Just a little Math the Crystal is 20ppm Tolerance so 0.002 Percent.
    Seconds in a Month = 30*24*60*60 = 2592000 seconds 
     2592000 * .002% = 52 seconds per month. Plus (or minus) aging. and temperature drift.
     
    #11
    Jim Nickerson
    User 452
    • Total Posts : 6185
    • Reward points : 0
    • Joined: 2003/11/07 12:35:10
    • Location: San Diego, CA
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/06 08:55:34 (permalink)
    0
    ninjabean
    JANickerson
    "minimal" is a nebulous amount, maybe you can state it in seconds ?


    Anything under 40PPM would be good enough. i.e. 20 minutes a year or 40us per second.


    Maybe an external part would do the job , I find this page https://www.maximintegrated.com/en/app-notes/index.mvp/id/3566
    #12
    ninjabean
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2014/02/25 16:55:09
    • Location: 0
    • Status: offline
    Re: PIC16F15323 Accuracy of Timer1 on FOSC/4 with External Crystal 2019/08/12 18:44:45 (permalink)
    0
    ric
    You didn't mention you are using MCC, and you have not shown the code in  TMR1_ISR() which is presumably where the important bit is happening.



    jtemples
    I don't use MCC; is this a macro?  Or is it a function with call/return overhead?  If the latter, does the MCC code compensate for that overhead?  Another reason not to use TMR1 in this fashion.




    Thank you ric and jtemples. The problem was the MCC generated TMR1_ISR(). The overhead on that thing is huge and takes about 100us to execute with a 1MHz system clock and MCC doesn't try compensate for it. I have removed that function, added my own compensation and the timing is much better (<20us per second across 4 samples).
     
    //Ideal: TMR1 = 3036, 62,500 counts @62.5KHz to rollover
    //TMR1 3038
    //TMR1H 11;
    #define TMR1H_VALUE 0x0B;
    //TMR1L 220 + 2(calibration)
    #define TMR1L_VALUE 0xDC+2;
     
    //---------------------------------------------------------
    if(PIE4bits.TMR1IE == 1 && PIR4bits.TMR1IF == 1)
            {
                // Clear the TMR1 interrupt flag
                PIR4bits.TMR1IF = 0;
                //Ideal: TMR1 = 3036, 62,500 counts @62.5KHz to rollover
                TMR1H = TMR1H_VALUE;
                TMR1L = TMR1L_VALUE; //2 count offset applied to compensate software loading of timer
                //TMR1_ISR();
    }

     
    ric
    To get an accurate count, it's better to get the hardware to do the reload.
    That would involve using the CCP module with timer 1, or using TMR2 with the programmable reload register to generate exact intervals (usually shorter than a second, but you can just count them to get seconds.)




    Thanks for the advice. I will try it if I need more accuracy.
    #13
    Jump to:
    © 2019 APG vNext Commercial Version 4.5