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.
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:
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.
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.
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:
bsf STATUS, RP0 ; Select Register Bank 1 (where the OSCCAL register is located)
bcf STATUS, RP0; Select Register Bank 0
This calls the memory location at 3ff
The assembler code at 3ff will be something like
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.
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.
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):
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.
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):
Use the top drop down menu to select Programmer Options.
Click the checkbox for "Program Calibration Memory" :
Now go to the Xc8 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:
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.
Sign up to the Microzine Newsletter (Free) to receive a download link for the code.
MPLAB X IDE : V3.30
XC8 compiler: V1.45
Arduino EEPROM: How to use it and How to presrve the life of EEPROM. Two examples sketches to save multiple values to EEPROM.
A tutorial on using the ADS1115 precision 16 bit ADC for low power use.
Learn how to use the TP4056 properly. There's a right, and a wrong way, to use it to safely charge Lithium Ion batteries.
The DW01A chip is a Lithium Ion battery protector commonly used on TP4056 boards. Find out Exactly how it works and how to use it the correct way.
For Arduino string operations you can use Object Class Strings or C style strings but which should you use? Also find out how to decode commands and control variables in your programs using strings.
Real Time Clock Design (FREE): A Free and Complete RTC design using the DS1307 and a PIC micro (16F88) also re-targetable. This PIC project uses an I2C Clock chip and 7-segment display to create a fou…