Calibrating PIC microcontroller internal oscillator
I am describing here a method to calibrate PIC micro-controllers.One
day I antecedently erased the the oscillator calibration value in my PIC
pic16f676.Then searched for a solution to recalibrate it.I found this
link from Microchip's website AN250 - Auto-calibration of the PIC12F6XX
Internal RC Oscillator .
But for this method needs an additional reference pulse generator of 5kHz.But I don't have these things.So I tried an alternate method.In this method, we need a PC with serial port to calibrate PIC micro-controller. Other things we needed are,
A compiler for PIC. I use PICC Lite edition.
PIC burning software . I use Picprog
Here is a simple c source code
Really this code is a modified version of code from "picc-9_82" package from microchip.com. This program will produce a "Hello wolrd ." string to PortA2. We can connect PortA2 to PC's serial port by using a max232 level shifter IC . I am using this circuit
Connect PIC to PC's RS232
and observe the output
Now copy and paste the clearly visible strings from this to a new text file
Now format it for the easiness of the observation.then choose the string from the middle.
I choose "Hello world. ##cg##".Now note the two characters between two "##" .Here it is cg
Know look at the source code let's understand how the 'cg' is produced.
suppose that myosccal=0x26. then its binary is "0010 0110"
first charector is produced by adding Bit 4-7 to 0x61
ie binary "0010" + 0x61 = 0x63 = Ascii charector 'c'
second charector is produced by adding Bit 0-3 to 0x61
ie binary "0110" + 0x61 = 0x67 = Ascii charector 'g'
So the original value of 'myosccal' is first_part . second_part. Here it is "0010 0110" = 0x26
So this is the calibration value of PIC's internal oscillator.
Now we can burn this to pic
I simply made a an asm file cal.asm
then converted into hex
then burned into PIC using picprog
But for this method needs an additional reference pulse generator of 5kHz.But I don't have these things.So I tried an alternate method.In this method, we need a PC with serial port to calibrate PIC micro-controller. Other things we needed are,
A compiler for PIC. I use PICC Lite edition.
PIC burning software . I use Picprog
Here is a simple c source code
#include <htc.h> #include <conio.h> __CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & CP_OFF & CPD_OFF & BOREN_OFF & MCLRE_OFF); /************************************* * Tunable parameters */ /* Transmit and Receive port bits */ #define TxData RA2 /* bit3 in port A */ #define XTAL 4000000 /* Crystal frequency (Hz). */ #define BRATE 1200 /* Baud rate. */ // #define BRATE 9600 /* Baud rate. */ #define RX_OVERSAMPLE 8 /* Amount of oversampling the receiver does. Must be a power of two */ #define TIMER_VALUE XTAL / (4 * BRATE * RX_OVERSAMPLE) // 1 start bit + 8 data bits + 2 stop bits + safe. #define TRANSMIT_NUM_BITS 13 #if (RX_OVERSAMPLE-1)&RX_OVERSAMPLE #error RX_OVERSAMPLE_value must be a power of 2 #endif static unsigned char sendbuffer; // Where the output char is stored. // it is received. static unsigned char send_bitno; static unsigned char myosccal; static bit tx_next_bit; #define LENGTH(a) (sizeof(a)/sizeof((a)[0])) const char* const text = "Hello world. "; /** * init_uart * * Initialises the serial port: * * Sets up the I/O directions for the appropriate PortA pins; * Sets up Timer0. * * */ void init_uart(void) { // skipoversamples = 1; // check each interrupt for start bit TRISA = 0x1B; // Set up I/O direction. TRISC = 0xFE; /* Set up the timer. */ T0CS = 0; // Set timer mode for Timer0. TMR0 = (2-TIMER_VALUE); // +2 as timer stops for 2 cycles // when writing to TMR0 T0IE = 1; // Enable the Timer0 interrupt. GIE = 1; } void putch(char c) { while(send_bitno) continue; tx_next_bit = 0; sendbuffer = c; send_bitno = TRANSMIT_NUM_BITS*RX_OVERSAMPLE; } interrupt void serial_isr(void) { // Reset Timer0 value // This is added to TMR0 because there is a delay to get to the isr. PORTC |= 1; TMR0 += -TIMER_VALUE + 4; // +2 as timer stops for 2 cycles when writing // to TMR0 +2 for tweak T0IF = 0; /*** TRANSMIT ***/ /* This will be called every RX_OVERSAMPLEth time * (because the RECEIVE needs to over-sample the incoming * data). */ if(send_bitno) { if((send_bitno & (RX_OVERSAMPLE-1)) == 0) { TxData = tx_next_bit; // Send next bit. tx_next_bit = sendbuffer & 1; sendbuffer = (sendbuffer >> 1) | 0x80; } send_bitno--; } PORTC &= ~1; } void main(void) { unsigned int i; init_uart(); myosccal = 0; OSCCAL=myosccal; while(1){ for(i=0;i<13;i++) putch(text[i%13]); putch('#'); putch('#'); putch(0x61+((myosccal/16)&0xF)); putch(0x61+(myosccal&0xF)); putch('#'); putch('#'); myosccal++; OSCCAL=myosccal; } }
Really this code is a modified version of code from "picc-9_82" package from microchip.com. This program will produce a "Hello wolrd ." string to PortA2. We can connect PortA2 to PC's serial port by using a max232 level shifter IC . I am using this circuit
Connect PIC to PC's RS232
screen /dev/ttyS0 1200,cs8,-parenb,-cstopb,-hupcl
and observe the output
Now copy and paste the clearly visible strings from this to a new text file
Now format it for the easiness of the observation.then choose the string from the middle.
I choose "Hello world. ##cg##".Now note the two characters between two "##" .Here it is cg
Know look at the source code let's understand how the 'cg' is produced.
putch(0x61+((myosccal/16)&0xF)); putch(0x61+(myosccal&0xF));
suppose that myosccal=0x26. then its binary is "0010 0110"
first charector is produced by adding Bit 4-7 to 0x61
ie binary "0010" + 0x61 = 0x63 = Ascii charector 'c'
second charector is produced by adding Bit 0-3 to 0x61
ie binary "0110" + 0x61 = 0x67 = Ascii charector 'g'
So the original value of 'myosccal' is first_part . second_part. Here it is "0010 0110" = 0x26
So this is the calibration value of PIC's internal oscillator.
Now we can burn this to pic
I simply made a an asm file cal.asm
list p=16f676 include "p16f676.inc" org 0x3ff ;address of calibration value retlw 0x26 ;0x26 is the calibration value end
then converted into hex
gpasm cal.asm
then burned into PIC using picprog
picprog --burn --erase --force-calibration -i cal.hex
Comments
Post a Comment