还有,12C508A是一次性编程的,并且0x1FF处的内容,我们是无法改变的,也就是说你在此处编写任何指令,编程器都不会为你烧写,或者说即使烧写了也不会改变其中的内容。

可12F629是FLASH器件,可多次编程,如果你没有故意选择,正品的编程器(如Microchip的PICSTART PLUS)是不会对存有校准值的程序空间进行编程的。即使你无意中对这个程序空间进行了编程,你也可以用一条RETLW 0xXX放在0x3FF处再编程一次就可以了,但这个XX值可能是不正确的,需经实验确定(请参考后面说明)。

为了检验OSCCAL的值对振荡器频率的影响,特编写了下面一个小程序进行验证:

#include

//*********************************************************__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & BOREN & PROTECT & CPD);//内部RC振荡器普通IO口;无效看门狗;上电延时;内部复位;掉电复位;代码保护;数据保护//*********************************************************#define out GPIO0 //定义输出端#define jc GPIO3 //定义检测端

//*********************************************************void interrupt zd(); //声明中断函数//主函数***************************************************void main(){

CMCON=7;

OPTION=0B00000011; //分频比为1:16,

TRISIO=0B11111110;

GPIO=0B00000000;

WPU=0;

T0IF=0;

GIE=1;

T0IE=1;

while(1){

if(jc)OSCCAL=0xFF;

else OSCCAL=0;

}

}

//中断函数*************************************************void interrupt zd(){

T0IF=0;

out=!out;

}

程序其实很简单,就是在中断中让out脚的电平翻转,翻转的时间为4096个指令周期,电平周期为8192个指令周期。而指令的周期又决定于RC时钟频率。在主程序中,不断的检测JC端口的电平,然后根据此端口电平的值修改OSCCAL寄存器的值。当然,最后从OUT脚的波形周期上反映出了OSCCAL寄存器的值改变。

经用示波器测量(抱歉,手边没有频率计),JC端接地时,OUT端的电平周期为9.5毫秒左右;而JC端接正电源时,OUT端的电平周期为6毫秒左右。也就是说OSCCAL的值越大,单片机的时钟频率越高。并且,这个变化范围是很大的,因此,如果使用PIC单片机的内部RC振荡器时,对其振荡频率进行校正是十分必要的。这也是我在做滚动码接收解码器时,产品离散性很大的原因。望大家以后使用内部RC振荡器时能够注意到此点。

但还有一点要注意,即使你对RC振荡器进行了校正,你也别指望这个4MHz的RC振荡器肯定会很标准,实际上它还是一个RC振荡器,它的振荡频率是电压、温度的函数,也就是说这个振荡频率会随着电压和温度的变化而变化,只是经校正后的值更接近4MHz罢了,这在产品开发的一开始就要注意的。