您的位置 首页 报告

PIC单片机RC振荡器的运用及校准办法

PIC单片机RC振荡器的使用及校准方法-12C508A的复位矢量是程序的最高字0x1FF,这个字节生产商已经固定的烧写为MOVLW 0xXX,指令执行后,W寄存器中即为校准值XX,当我们需要校准时,那么,在紧接着的地址0x0应该是一条这样的指令:MOVWF OSCCAL。接下去RC振荡器就会以标准的振荡频率运行了。

在PIC单片机中有多种类型有内部RC振动器的功用,然后省去了晶振,不光节省了本钱,而且咱们还多了两个IO端口可以运用。

可是,因为RC振动器中电阻电容的离散性很大,因而,在有内部RC振动器的单片机中,它的内部RAM中都会有一个名为OSCCAL的校准寄存器,经过置入不同的数值来微调RC振动器的振动频率。而且,单片机的程序存储器中,也会有一个特别的字来贮存工厂出产时测得的校准值。下面我以常用的12C508A和12F629为例加以阐明。


P%&&&&&%单片机RC振动器的运用及校准办法

12C508A的复位矢量是程序的最高字0x1FF,这个字节出产商现已固定的烧写为MOVLW 0xXX,指令履行后,W寄存器中即为校准值XX,当咱们需求校按时,那么,在紧接着的地址0x0应该是一条这样的指令:MOVWF OSCCAL。接下去RC振动器就会以规范的振动频率运转了。

12F629的校准值也存放在最高字--0x3FF中,内容是RETLW 0xXX,但它的复位矢量却是0x0。这样,在咱们需求校准RC振动器时,在初始化过程中要加上下面两句:

CALL 0x3ff

MOVWF OSCCAL

当然,你还要留意寄存器的块挑选位。

曾经,我在做项目时,没太留意这个问题,这是因为在运用12C508A时,HI-TECH在进行编译时现已偷偷地替咱们做了这项作业。它会在程序的0x0处主动加一条MOVWF OSCCAL。用12F629做接纳解码替代2272时也没发生什么问题,可是在用被它作翻滚码解码器时却发现接纳间隔的离散性很大。经屡次试验总算找出是没对振动器的振动频率进行校对所至。

因而,需求别的编写用于校对的句子,我用了两种办法来完成这个意图:

1、用内嵌汇编的方式

#asm //此段汇编程序用于将坐落程序段3FFH的

call 3ffh //内部RC振动器的校准值放入校准寄存器,

bsf _STATUS,5 //在进行C言语调试时应屏蔽这段程序

movwf _OSCCAL

#endasm

2、用C言语规范方式

const unsigned char cs @ 0x3ff; //在函数体外

。..

OSCCAL=cs; //仿真时屏蔽此句

用这两种办法都有一个小缺点--仿真时,程序无法运转,这是因为C编译器并没有为咱们在0x3FF放置一条RETLW 0xXX的句子。因而,程序运转到这儿之后,并没有把一个常数(校准值)放入W寄存器然后回来,而是持续履行这条句子的下一句--0x0及其之后的程序,也就是说程序到此就乱了。因而如程序后边注释所示,在仿真时,应先屏蔽这几句程序。在程序调试完成后,需求烧写时,把注释符去掉,再编译一次就可以了。

我还有一种主意,不必屏蔽句子,那就是用函数来完成,就是在0x3FF起树立一个函数,函数体内只要一条句子,如下:

char jz()

{

return 0;

}

当然,还要考虑C函数回来时,一定会挑选寄存器0,实际上这个函数的开始地址应小于0x3FF。可是我找了我所能找到的参阅资料,并上网找了屡次,也没找到为函数肯定定位的办法,期望有知道的朋友点拨一下。

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

可12F629是FLASH器材,可屡次编程,假如你没有成心挑选,正品的编程器(如MicrochipPICSTART 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算了,这在产品开发的一开始就要留意的。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ceping/baogao/345713.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部