ESSEMI华东FAE 发表于 2020-5-29 09:49

一种东软载波单片机内部低速时钟频率校准方法

引言
        通常单片机的内部低速时钟(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);                                                                                         }                                                                                     }                                                                                }                                       
                                       

asdsfgwsafd 发表于 2020-6-1 15:59

HR8P506 测温的例程有吗 下载到的库里只有AD的
页: [1]
查看完整版本: 一种东软载波单片机内部低速时钟频率校准方法