打印
[国产单片机]

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

[复制链接]
825|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

2

帖子

0

粉丝