2
\$\begingroup\$

I am trying to calibrate the internal clock to turn on a output once for 3 seconds every 7 days within a few minutes accuracy. I was able to accomplish this using the OSCCAL register in the chip. The problem this on works if I set this per chip. I am trying to find a way to program it by have it check and calibrate its internal while programming. Maybe there is a feature in the compiler that will auto calibrate?

I am using:

MCU: PIC10F200

Programmer: PICkit3

Software: MPLAB X IDE v3.26

Compiler: XC8 v1.37

\$\endgroup\$
4
  • \$\begingroup\$ Have you considered a dedicated RTCC real-time-clock-calendar IC? There are many variants out there which use little power (seen down to 15nA!) and can wake up a MCU upon certain date and time. \$\endgroup\$
    – rdtsc
    May 5, 2016 at 16:06
  • \$\begingroup\$ Maybe not. Are you aware that there's a factory calibration value for OSCCAL in the flash memory at location 0x00FF? See page 11 of the datasheet. \$\endgroup\$
    – Dave Tweed
    May 5, 2016 at 16:06
  • 1
    \$\begingroup\$ In order for it to check & auto-calibrate itself it would need access to a reference clock with an accuracy which you think is accurate enough. How else would the PIC know that its own clock needs calibrating? \$\endgroup\$
    – brhans
    May 5, 2016 at 16:37
  • \$\begingroup\$ I would guess that you can't achieve repeatable minutes of precision over a week using the PIC internal oscillator, even with calibration. Because of part-to-part variation, the compiler could not correct for the frequency difference between different chips. Even with calibration, ±1% frequency accuracy of the 4MHz oscillator (Table 12-3, page 64) won't work out in your favor. \$\endgroup\$ May 5, 2016 at 16:40

1 Answer 1

4
\$\begingroup\$

The compiler cannot 'auto calibrate' because it has no idea what frequency an individual chip may run at. The chip programmer/debugger could do it by downloading and running a program in the PIC which produces a frequency on an output pin. Then this frequency could be measured, and the required OSCCAL calibration value calculated and inserted into your code.

Normally you don't need to do this because Microchip has already done it at the factory. A calibration byte is stored in the last ROM location in a MOVLW (MOVe Literal byte to Working register) instruction. On power up or reset the PIC executes this instruction, so the W register has the calibration byte in it on startup. Your startup code just has to save this value (before any other code that uses the W register!) and write it to the OSCCAL register.

Factory calibration is probably not as accurate as it could be because it is done quickly and not in the exact circuit you have. You might be able to get slightly better accuracy with a PIC program that incrementally sets OSCCAL to different values until it gets as close as possible to the required frequency (perhaps by comparing it a reference frequency on an input pin) then tells you what calibration value to use. Here's an example:-

Internal Oscillator Recalibration Utility

(Note: the project in that link only works with the 12F629 and 675. The 10F200 has no EEPROM, so you would have to use some other method of extracting the calibration value, eg. send it as serial data on an output pin.)

But 7 days is 10080 minutes. The PIC10F200 has an internal oscillator tolerance of +-1% at 3.5V, which corresponds to +-100 minutes in 7 days. So even with the best calibration you cannot guarantee to get an accuracy of 'a few minutes'.

\$\endgroup\$
2
  • \$\begingroup\$ And what will supply voltage and temperature variation do to the error? An XO pretty much needs to be used for "close" time measurements... a TCXO for "good" timekeeping... and rubidium for "accurate" time. Either that, or sync the time to a Time Signal Receiver and correct the time periodically. \$\endgroup\$
    – rdtsc
    May 5, 2016 at 23:33
  • \$\begingroup\$ The internal RC oscillator is obviously not good enough. He needs about +-0.02% accuracy, so a standard crystal should be fine. That takes up up 2 pins, leaving one input and one output - which hopefully will be enough to do the job... \$\endgroup\$ May 6, 2016 at 1:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.