版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
精品文档-下载后可编辑PIC单片机RC振荡器的使用及校准方法-设计应用在PI)C的单片机)中有多种型号有内部RC振荡器)的功能,从而省去了晶振,不但节省了成本,并且我们还多了两个IO端口可以使用。
但是,由于RC振荡器中电阻)、电容)的离散性很大,因此,在有内部RC振荡器的单片机中,它的内部RAM)中都会有一个名为OSCCAL的校准寄存器),通过置入不同的数值来微调RC振荡器的振荡频率。并且,单片机的程序存储器中,也会有一个特殊的字来储存工厂生产时测得的校准值。下面我以常用的12C508A和12F629为例加以说明。
12C508A的复位矢量是程序的字0x1FF,这个字节生产商已经固定的烧写为MOVLW0xXX,指令执行后,W寄存器中即为校准值XX,当我们需要校准时,那么,在紧接着的地址0x0应该是一条这样的指令:MOVWFOSCCAL。接下去RC振荡器就会以标准的振荡频率运行了。
12F629的校准值也存放在字--0x3FF中,内容是RETLW0xXX,但它的复位矢量却是0x0。这样,在我们需要校准RC振荡器时,在初始化过程中要加上下面两句:
CALL0x3ff
MOVWFOSCCAL
当然,你还要注意寄存器的块选择位。
以前,我在做项目时,没太注意这个问题,这是因为在使用12C508A时,HI-TE)CH在进行编译时已经偷偷地替我们做了这项工作。它会在程序的0x0处自动加一条MOVWFOSCCAL。用12F629做接收解码代替2272时也没发生什么问题,但是在用被它作滚动码解码器时却发现接收距离的离散性很大。经多次试验终于找出是没对振荡器的振荡频率进行校正所至。
因此,需要另外编写用于校正的语句,我用了两种方法来实现这个目的:
1、用内嵌汇编的形式
#asm//此段汇编程序用于将位于程序段3FFH的
call3ffh//内部RC振荡器的校准值放入校准寄存器,
bsf_STATUS,5//在进行C语言调试时应屏蔽这段程序
movwf_OSCCAL
#endasm
2、用C语言标准形式
constunsignedcharcs@0x3ff;//在函数体外
。..
OSCCAL=cs;//仿真时屏蔽此句
用这两种方法都有一个小缺陷--仿真时,程序无法运行,这是由于C编译器并没有为我们在0x3FF放置一条RETLW0xXX的语句。因此,程序运行到这里之后,并没有把一个常数(校准值)放入W寄存器然后返回,而是继续执行这条语句的下一句--0x0及其之后的程序,也就是说程序到此就乱了。因此如程序后面解释所示,在仿真时,应先屏蔽这几句程序。在程序调试完成后,需要烧写时,把解释符去掉,再编译就可以了。
我还有一种想法,不用屏蔽语句,那就是用函数来实现,就是在0x3FF起建立一个函数,函数体内只有一条语句,如下:
charjz()
{
return0;
}
当然,还要考虑C函数返回时,一定会选择寄存器0,实际上这个函数的起始地址应小于0x3FF。但是我找了我所能找到的参考资料,并上网找了多次,也没找到为函数定位的方法,希望有知道的朋友指点一下。
还有,12C508A是性编程的,并且0x1FF处的内容,我们是无法改变的,也就是说你在此处编写任何指令,编程器都不会为你烧写,或者说即使烧写了也不会改变其中的内容。
可12F629是FLASH器件,可多次编程,如果你没有故意选择,的编程器(如Microchip)的PICSTARTPLUS)是不会对存有校准值的程序空间进行编程的。即使你无意中对这个程序空间进行了编程,你也可以用一条RETLW0xXX放在0x3FF处再编程就可以了,但这个XX值可能是不正确的,需经实验确定(请参考后面说明)。
为了检验OSCCAL的值对振荡器频率的影响,特编写了下面一个小程序进行验证:
#include
//*********************************************************
__CONFIG(INTI)OWDTDISPWRTENMCLRDISBORENPROTECTCPD);
//内部RC振荡器普通IO口;无效看门狗);上电延时;内部复位;掉电复位;代码保护;数据保护
//*********************************************************
#defineoutGPIO0//定义输出端
#definejcGPIO3//定义检测端
//*********************************************************
voidinterruptzd();//声明中断函数
//主函数***************************************************
voidmai)n()
{
CMCON=7;
OPTION=0B00000011;//分频比为1:16,
TRISIO=0B11111110;
GPIO=0B00000000;
WPU=0;
T0IF=0;
GIE=1;
T0IE=1;
while(1){
if(jc)OSCCAL=0xFF;
elseOSCCAL=0;
}
}
//中断函数*************************************************
voidinterruptzd()
{
T0IF=0;
out=!out;
}
程序其实很简单,就是在中断中让out脚的电平翻转,翻转的时间为4096个指令周期,电平周期为8192个指令周期。而指令的周期又决定于RC时钟)频率。在主程序中,不断的检测JC端口的电平,然后根据此端口电平的值修改OSCCAL寄存器的值。当然,从OUT脚的波形周期上反映出了OSCCAL寄存器的值改变。
经用示波器)测量(抱歉,手边没有频率计),JC端接地时,OUT端的电平周期为9.5毫秒左右;而JC端接正电源时,OUT端的电平周期为6毫秒左右。也就是说OSCCAL的值越大,单片机的时钟频率越高。并且,这个变化范围是很大的,因此,如果使用PIC单片机的内部RC振荡器时,对其振荡频率进行校正是十分必要的。这也是我在做滚动码接收解码器时,产品离散性很大的原因。望大家以后使用内部RC振
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论