Thursday, August 12, 2010

The internal oscillator in the pic12f629

Recently I’ve been using the small pic12f629. My interest was to use it as a cheap D/A converter using PWM. Unfortunately, I chose this pic at the store without check the characteristics first, yeah, I know, how stupid of me! :-(
I thought it had a PWM module as well as a ADC converter, but not, no PWM and no ADC, but anyway, for my purposes it could works! Also, the price was good! just 1000 yen for 10 SO chips plus one DILP!  :-)
So, I present a program to read three inputs “quasi-digital” coming from a FSR sensor and then, according to the inputs, the pic will generate a PWM signal with width of pulse depending on the combination of the input signals.
This PWM signal will be then filtered and thus converted to analog signal. Quite easy, right?
For save pins money and space I decided to use the internal oscillator, the data sheet says that it has one 4MHz internal oscillator.


image
image
The interesting thing with this uC is that, it has a calibration number for the oscillator, which means that, to run at 4MHz its necessary to load an specific value in the register OSCCAL.
This value is specific for each chip and it is stored in the last position of the flash memory, the register 0x03FF.
image
Then, in order to load this value in the OSCCAL calibration, in your program you have to address to that location as a call subroutine or directly load the value in the register. Obviously you have to be careful to do not erase that register before take note of the number or your uC will be almost useless.
#include <12F629.h>
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD,NOMCLR,BANDGAP_HIGH
#use delay(clock=4000000)
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#byte OSCCAL = 0x90
#rom 0x03FF={0x34ff}
unsigned int temp;
void init()
{
OSCCAL = 0xff; // set internal oscillator to mid frequency
set_tris_a( 0b11001011 ); // set GP0-GP1-GP3 input, all other outputs
setup_comparator( NC_NC_NC_NC ); // disable comparators
#use fast_io (A)
}
main()
{
init();
while (TRUE) // Repeat forever
{
temp=0;         //Erase variable and 
output_low (GP4);  //clean pines
output_low (GP5);
if(input(GP0))   //If the input1 is high
{
temp=30;          //prepare one specific duty
output_high (GP4); //indicate turning on a LED
}
if (input(GP1))   //in input two
{
temp=temp+60;    //add duty 
output_high (GP5);
}
if (input(GP3))  //input three
{
temp=temp+109;   //add more duty
output_high (GP4);
output_high (GP5);
}
//made a cycle toggling the output acording to the delay acumulated
output_low(GP2);
delay_us(199-temp ); // wait 250ms
0ms
output_high(GP2); // turn LED off
delay_us(temp+1); // wait 250ms
output_low(GP2);
}
}
I intended to use the timer 1 and 2 as a PWM module but the pic running at 4MHz was to slow to generate a fast PWM and a little cumbersome, so I decided employ a awful and not nice at all, very-simple-algorithm. Which actually, is not a real PWM, just looks like at the output.
Anyway, the point I want to save here, is: How to configure the pic to use the internal oscillator and to load the OSCCAL value.
By the way, the program is working but I still need to check if the results are good enough for my application.

No comments:

Related Posts Plugin for WordPress, Blogger...