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