12F675 OSCCAL Calibration

Find out how get your 12F675 OSCCAL calibration value back. It's quite easy to lose the OCSCAL value as it is written into the upper word of program memory. So if you erase program memory then you lose it.

The MPLAB X tools are quite careful to stop overwriting this memory location so it is unlikely that you will lose them (but it can happen). The fact that MPLAB X stops overwrites also presents a problem as you have to know how to use the MPLAB X tool to force it to write to that memory address! - see below on how to do this.

Warning: If you do not use a special piece of code to access the data in the end of memory location then the OSCCAL value will never be written into the OSCCAL register meaning all your timings will be way off. It is no good just updating the end of word memory location with the correct value - In every program for the 12F675 you must access and use that value by writing code into your program (see here).
Note: Although this page does not go over the process of recovery, the brownout level bits can also be lost. Recovery will be easier involving lowering the supply voltage until reset. The brown out bits are also factory calibrated.

To perform this calibration you need a frequency counter. You can find a free one on this site here - this project uses a 16F877A but most PIC micros with a TIMER1 and enough pins for an LCD drive will work if you adjust the code according to the processor.

The basic accuracy of the internal clock is 1% and is adjusted by setting the 12F675 OSCCAL value in the OSCCAL register. Every program, at start up, must write to the OSCCAL register having first obtained the stored calibration value.

The following program allows you to recalibrate the 12F675 internal oscillator by outputting the internal clock (GP4) which you then feed into a frequency counter. Buttons attached to GP3 and GP2 allow you to manually adjust the 12F675 oscillator calibration value up and down in increments of 4 (this is because the lower 2 bits are not used for the OCSCAL value).

For the 12F675 the internal oscillator is running at 4MHz so the output frequency on the CLKOUT output pin will be 1MHz (Fosc/4).

Since the accuracy is to be 1% that means the 1MHz reading must be within 10kHz of 1MHz. So your calibration will be accurate to +/-10kHZ plus the accuracy of the frequency meter.

If you use the design on this site and have a 100ppm 4MHz crystal as the processor clock then:

  • A 100ppm error in 4MHz is 400Hz.
  • 400/4e6 *100 is a 0.01% error.
  • You can also say that 100ppm is 100/1e6 and in percentage that is (100/1e6)*100=0.01%.

Therefore the total error will be 1.01% so you can say that the meter adds virtually no error component as the 1% accuracy (actually the error) specification far outweighs the meter error.

12F675 Calibration Schematic

The schematic below shows the 12F675 programmer circuit (the top part). It is split into two to so that you can see the idea of moving the 12F675 from the programming area (top) to the application area (bottom) using a solderless breadboard.

When programming the 12F675 you can sometimes get away with putting circuitry on the programming connections (ICSP) PGC and PGD but not if you place LEDs and loads there, so it is just easier to move the device from top to bottom. Program at the top and test at the bottom.

12F675 Calibration OSCCAL schematic

Using the 12F675 OSCCAL value

The fact that the OSCCAL value is stored in upper memory is fine but if you do not use that value then the oscillator will still be uncalibrated. You must do something in your code!

The OSCCAL register allows for a wide variance in basic oscillator value and you will find that oscillator output does in fact vary widely between devices- so calibration (and use of calibration data) is necessary to get the 1% accuracy.

In the 12F675 data sheet this is the recommended way (using assembly language) to get the OSCCAL value into the OSCCAL register:

Using OSCCAL in assembler

bsf STATUS, RP0 ; Select Register Bank 1 (where the OSCCAL register is located)

call 3ffh

movwf OSCCAL

bcf STATUS, RP0; Select Register Bank 0

This calls the memory location at 3ff

The assembler code at 3ff will be something like

retlw 20h

Where 20h is the stored calibration value and retlw means return with literal in W - the literal is the value at the stored in the memory: here 20h.

Using OSCCAL in C code with XC8

In XC8 (THE MPLAB X 8-bit compiler) a macro is provided that does the same as the above assembler code:

OSCCAL = __osccal_val(); // Use when good cal value is stored at 0x3ff.

The above code (or variant for other compilers) should always be called at the start of your code.

Software Operation

Program the chip and move it to the lower test area.

On power up the LED flashes slowly 5 times. If this does not happen program a different OCSCAL value using the method below e.g. put in the value 20h.

Observe the frequency counter value and press the left button to lower the OCSCAL value by 4 and the right button to increase it by 4. OSCCAL is shifted left by 2 bits so values increase 4 at a time (to increase the OSCCAL register by 1):

OCSCAL regsiter for PIC12F675

To confirm you have pressed a button the LED flashes once for each press.

Once you see that the frequency reading is within 10000Hz (10kHz) of 1MHz then this is the calibration value you want. To find out what it is press both buttons together. The led now flashes to the value of the current OSCCAL (divided by 4).

So count the flashes, multiply by 4 (to get the value needed to put into the OSCLCAL register) then convert to hex ready for MPLAB X.

So if you get 8 flashes, multiplying by 4 gives 32 decimal and results in 0x20 as the hex OCSCAL value.

Programming the OSCCAL value : MPLAB X method.

To program the protected end of memory area you need to setup two configuration options in MPLAB X.

First the programmer and then the XC8 linker.

Use Menu File > Project Properties, then select PICkit 3 (the programmer):

mplab config

Use the top drop down menu to select Programmer Options.

MPLABX select program options

Click the checkbox for "Program Calibration Memory" :

MPLAB X program options

Now go to the Xc8 linker options:

MPLAB X linker options

Click calibrate oscillator and set the OSCCAl value you want preceded by 0x34 (this is the RETLW code) e.g. for 0x20 calibration value use 0x3420:

MPLAB X OSCCAL value setting

Now program the chip and you'll be asked to allow programming of the cal value at 0x3ff.

Don't forget to unclick the program options when finished.

12F675 OCSCAL Code Download

Sign up to the Microzine Newsletter (Free) to receive a download link for the code.

Software Versions


XC8 compiler: V1.45


Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.

Privacy Policy | Contact | About Me

Site Map | Terms of Use