N76E003内部有两个RC振荡器——16M(HIRC)、10K(LIRC)。高速16MHz误差在出厂时校准到±2%(全温度、全电压范围内),而10K低速振荡器,据说是35%的误差,一个小时定时,多出十几分钟就不足为奇了。
以下代码源于新唐官方例程,其运行原理大概是同时使用HLRC&LIRC定时器,两者同时开启,LIRC定时固定时间,溢出后查看HIRC计数值,求出差值(时间越短越精确),用于校准LIRC。
但在实际测试中,效果不理想,可能是个别芯片的问题,**大家也能进行测试
//***********************************************************************************************************
// File Function: N76E003 wake up timer self calib demo code
//***********************************************************************************************************
#include <stdio.h>
#include "N76E003.h"
#include "Define.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
#define TIMER_DIV12_VALUE_25_6ms 65536-34134 //34134*(12/16)=45000 us = 25.6 ms
#define TIMER_DIV12_VALUE_45ms 65536-60000 //60000*(12/16)=45000 us = 45 ms // Timer divider = 12
#define TIMER_45MS_BEGIN 5536
#define TIMER_30MS 40000 //40000*(12/16)=30000 us = 30 ms
#define TIMER_24MS 32000 //32000*(12/16)=24000 us = 24 ms
/******************************************************************************
* FUNCTION_PURPOSE: 自唤醒定时器定时中断服务程序
******************************************************************************/
void WakeUp_Timer_ISR (void) interrupt 17 //ISR for self wake-up timer
{
P12=~P12;//翻转管脚
// clr_TR0;
// THReg = (TH0);
// THReg = (THReg<<8)|TL0;
// printf("\n%x",THReg);
clr_WKTF; //清除中断标志位
}
/******************************************************************************
* FUNCTION_PURPOSE: 设定定时器0计数45ms
******************************************************************************/
void Timer0_Delay45ms()
{
clr_T0M; //T0M=0, Timer0 Clock = Fsys/12
TMOD |= 0x01; //Timer0 is 16-bit mode
//Trigger Timer0
TL0 = LOBYTE(TIMER_DIV12_VALUE_45ms);
TH0 = HIBYTE(TIMER_DIV12_VALUE_45ms);
// set_TR0;
// THReg = (TH0);
// THReg = (THReg<<8)|TL0;
// printf("\nbegin %x",THReg);
}
/******************************************************************************
* FUNCTION_PURPOSE: 启动自唤醒定时器和定时器0同时开始计数
******************************************************************************/
void startCheck()
{
clr_WKTF;
WKCON = 0x00; //timer base 10k, Pre-scale = 0, 不除频,一个时钟0.1 ms
// RWK = 0XFF; // if prescale is 0x00, never set RWK = 0xff
RWK = 0xF; //240 个时钟 24 ms
// set_EWKT; // enable WKT interrupt
set_WKTR; // Wake-up timer run
// EA =1;
set_TR0;
}
/******************************************************************************
* FUNCTION_PURPOSE: 校准函数
返回一个比值(实际定时器0跑的计数值与理论计数值的比值)
10K内部时钟(自唤醒定时器)和16MHZ 内部高速时钟(定时器0) 同时开始计数
计数20ms,当自唤醒定时器停止时,再去停止定时器0,读取当前定时器0的计数值。
然后使用定时器0实际跑的值除以20ms对应计数器的值。
******************************************************************************/
float HIRCCheck10KRC(void)
{
float temp,a,b;
UINT16 THReg =0;
Timer0_Delay45ms();
startCheck();
while(!(WKCON&0x10));
clr_TR0;
clr_WKTF;
THReg = (TH0);
THReg = (THReg<<8)|TL0;
a = THReg- TIMER_45MS_BEGIN;
b = TIMER_24MS;
temp = a/b;
return temp;
// printf("\n%x",THReg);
// printf("\n%f",temp);
}
/******************************************************************************
* FUNCTION_PURPOSE: 测试自唤醒定时器计数
******************************************************************************/
void testSelfWakeUPTimer(float scale)
{
UINT16 temp;
temp = 200 /scale;
WKCON = 0x00; //timer base 10k, Pre-scale = 0, 不除频,一个时钟0.1 ms
// RWK = 0XFF; // if prescale is 0x00, never set RWK = 0xff
RWK = 0XFF-temp; //200 个时钟 20 ms
// set_EWKT; // enable WKT interrupt
set_WKTR; // Wake-up timer run
// EA =1;
while(!(WKCON&0x10));
clr_WKTF;
P12=~P12;
}
/************************************************************************************************************
* Main function
************************************************************************************************************/
void main (void)
{
float rScale;
UINT8 iCount=0;
Set_All_GPIO_Quasi_Mode;
InitialUART0_Timer3(115200);
// Timer0_Delay45ms();
rScale=HIRCCheck10KRC();
while(1)
{
rScale=HIRCCheck10KRC();
printf("\n%f",rScale);
Timer2_Delay1ms(100);
for(iCount = 0;iCount<100;iCount++)
{
testSelfWakeUPTimer(rScale);
testSelfWakeUPTimer(1);
}
}
}
————————————————
版权声明:本文为CSDN博主「XS30」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014798590/article/details/94721048
|