引言
通常单片机的内部低速时钟(LRC)精度比内部高速时钟(HRC)低,温漂也比内部高速时钟大,无法用LRC实现较精确低功耗计时。本文提供了一种LRC频率实时校准方法,可满足使用看门狗唤醒实现较精确低功耗计时功能。 LRC频率校准思路
上海东软载波微电子的8位单片机HRC时钟和LRC时钟都可用作ADC时钟源。使用精度更高的16M HZ HRC时钟计算ADC完成1次采样和转换的时间可以确定LRC的频率。通过修改WDTCAL寄存器值,调整LRC频率到期望值。 下面的例程通过这种方法,将LRC校准到31.25KHZ。本文以ES7P003为例,但也适用于东软其他7P芯片型号。 LRC频率校准例程 例程说明: 主函数中一开始先对LRC频率做1次粗调,使其达到31.25KHZ±1%。 程序主循环中一直处于休眠/唤醒中,每次WDT唤醒后做1次细调,通过多次调整最终达到31.25KHZ±0.3%。 程序中将ADC采样时间配置成2个ADC时钟周期,则采样和转换的时间是2+14个ADC时钟周期。 T21使用HRC的8分频作为时钟,16个ADC时钟周期完成时,T21的计数值timer为:(2+14)*TADC/TT21,其中TADC是ADC时钟周期,TT21是T21定时器计数周期。LRC频率应为31.25KHZ,因此timer=(2+14)/31250KHZ*2MHZ=1024,程序里在粗调和细调时对timer的合理范围放宽到1024±9和1024±3。
C例程: #include <hic.h> static volatile unsigned char section8 CALPROT @ 0xFFC0; static volatile unsigned char section8 WDTCAL @ 0xFFC3; unsigned int timer; void ChangeLRCFrq(unsigned int cv) { __asm {BSSBKSR,4} CALPROT =0x55; WDTCAL =WDTCAL+cv; __asm {BCCBKSR,4} } /********************************************************* 函数名: void main(void) 描 述: 主函数 **********************************************************/ void main(void) { ANSL = 0xFF; PA = 0x00;//输出低电平 PB = 0x00; PC = 0x00; PAT = 0x00;//管脚配置为输出 PBT = 0x00; PCT = 0x00; WDTC = 0x0D;//使能WDT,64分频,溢出时间约0.5s ANSL0 = 0; ADCCL =0x05;//运行A/D转换器,硬件控制采样,AIN0 ADCCH =0xF0;//ADC采样时间为2个ADC时钟,采样值低位对齐,A/D转换时钟频率为LRC ADTRG = 1; while(ADTRG); T21CL =0x00; //定时器模式 T21CM =0x07; //预分频1:8 T21EN =1; //使能T21
//校准LRC频率(粗调) while((timer<1015)|| (timer>1033)){ ADIF= 0; T21L= 0; T21H= 0; ADTRG = 1; while(ADIF== 0); timer =(T21H<<8) + T21L; if(timer <1015){//-1% ChangeLRCFrq(-1); } elseif(timer > 1033){//+1% ChangeLRCFrq(1); } }
while(1){ __AsmIDLE;//进入睡眠模式,等待WDT溢出唤醒 PA4 =~PA4; //校准LRC频率(细调) ADIF = 0; T21L = 0; T21H = 0; ADTRG = 1; while(ADIF == 0); timer= (T21H<<8) + T21L; timer = timer - 75;//补偿 if(timer <1021){//-0.3% ChangeLRCFrq(-1); } elseif(timer > 1027){//+0.3% ChangeLRCFrq(1); } } }
|