上海网站建设高端定制网络服务公司,北京校园网站建设,安康市天然气公司,衡阳有实力seo优化最近看了一些关于RTC校准的帖子#xff0c;发现很多人存在疑惑。正好最近我也在STM32中实现了RTC校准。发些心得。这些对老手来说有些罗索#xff0c;但对新手有益处。
实现RTC 校准的核心之一是库文件Stm321f0x_bkp.c中的void BKP_SetRTCCalibrationValue (uint8_t Calibra…最近看了一些关于RTC校准的帖子发现很多人存在疑惑。正好最近我也在STM32中实现了RTC校准。发些心得。这些对老手来说有些罗索但对新手有益处。
实现RTC 校准的核心之一是库文件Stm321f0x_bkp.c中的void BKP_SetRTCCalibrationValue (uint8_t CalibrationValue) 函数。谈到RTC校准的相关参考文档包括AN2604.pdfAN2821.pdf和AN2821.zip。这三个文档都可以从STM32官方网站下载。
按照AN2604.pdf描述的原理RTC 的校准值应在0-127之间。可实现的校准误差对应为0-121ppm。相当于每30天跑快的秒数为0-314s。
这里应注意的一个关键问题是RTC只能对跑快进行校准不能对跑慢进行校准。如果手表晶振的标称频率是32768Hz设其可能的误差范围是±2Hz则实际频率会在32766Hz-32770Hz之间。如果RTC的内部分频系数设定为32768则32768Hz是不需要校准的频率32768Hz-32770Hz是可以校准的频率最大校准能力大概是32772Hz。但是32766Hz-32768Hz的跑慢频率段则无法实现校准。为此在推荐的校准方法中使用32766代替32768作为分频系数。这样一来32766Hz是不需要校准的频率32766Hz-32770Hz是可以校准的频率范围。
剩下的问题是如何测量误差并以此得出校准值。一般来说有两种方法一是测量TamperPin的频率值然后计算ppm误差二是实际运行一定的天数与标准时钟做对比先得到每30天跑快的秒数然后计算ppm误差。
AN2604.pdfAN2821.pdf里都详细描述了第一种方法。AN2821.zip则使用定时器T2对TamperPin的频率值进行自动测量实现了自动校准。自动校准确实简化了用户操作但是它要依赖于8MHz主时钟的精度。自动校准不可能达到比8MHz主时钟精度更高的结果。所以给用户留有手动校准界面仍是万全之策。即使有自动校准也可以手动、自动叠加作用。
另一方面使用第一种方法进行校准需要准确测量TamperPin的频率值比如达到511.xxxHz的精度。普通示波器做不到这一点一般的频率计也不行高精度的频率计才可以。只有搞计量的专业人士才会有这种设备。作为搞控制系统的人搞一个非计量精度的时钟使用第一种方法还是有困难的。
第一种方法也好第二种方法也罢核心都是计算ppm误差。我们先看一下第一种方法是如何计算ppm误差的。由于使用了32766作为分频系数因此32766Hz是不需要校准的基准频率。不要把32768Hz看得太重现在它啥也不是32766Hz可看成新的标称频率。TamperPin的频率应为32766Hz/64511.968Hz。这也就是文档中计算误差时反复使用的基准频率。按照文档中所举的例子若实测TamperPin的频率为511.982Hz则误差为27.35ppm。计算过程为511.982Hz-511.968Hz/ 511.968Hz *10^6 27.35ppm。文档最后给出最接近的校准值为28。注意这里是最后的校准值28是由27 ppm查表得到的而不是有些帖子中误解的将27.35ppm近似成28ppm。
其实ppm误差的计算公式为ppm误差偏差/基准值*10的6次方。据此采用第二种方法时先得到了每30天跑快的秒数。这跑快的秒数就是偏差而30天就是基准值。所以ppm误差每30天跑快的秒数/30天*24小时*3600秒*10的6次方。用这个公式可以容易地解释文档AN2604.pdf中提到的“0.65ppm大约是每月误差1.7秒”。因为1.7/(30*24*3600)*10^6 0.65ppm。
计算出了ppm误差还要解决查表。对文档中给出的表格也不必看重。弄明白这个表格是怎么来的之后可以使用简单的计算公式代替查表。AN2604.pdf中说若校准值为1则RTC 校准时每2的20次方个时钟周期扣除1个时钟脉冲。这相当于0.954ppm(1/2^20*10^6 0.954)。而校准值最大为127所以最大可以减慢121ppm(0.954ppm*127 121)。所以这个校准表就是由简单的乘除运算得来的当然要使用浮点运算才可以得到准确结果。
以下是采用第二种方法实现的RTC 校准程序。
首先定义了两个常数一是PPM_PER_STEP准确到浮点数可表示的精度数0.9536743ppm。另一个是PPM_PER_SEC即每30天快一秒对应的ppm误差准确到浮点数可表示的精度数0. 3858025ppm。
#define PPM_PER_STEP 0.9536743 //10^6/2^20.#define PPM_PER_SEC 0.3858025 //10^6/(30d*24h*3600s).然后定义全局变量FastSecPer30days。通过用户菜单设定并传递到RTC校准程序里。u16 FastSecPer30days 117; //菜单输入。117只用于演示。
实现的校准函数为
void RTC_Calibration(void){float Deviation 0.0;u8 CalibStep 0;Deviation FastSecPer30days * PPM_PER_SEC; //得到ppm误差Deviation / PPM_PER_STEP; //得到校准值的浮点数CalibStep (u8)Deviation; // 得到校准值的整形数if(Deviation (CalibStep 0.5))CalibStep 1; //四舍五入if(CalibStep 127)CalibStep 127; // 校准值应在0—127之间BKP_SetRTCCalibrationValue(CalibStep); //调用库函数}//函数结束RTC_Calibration