打印
[综合信息]

小华 RTC补偿值计算

[复制链接]
406|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在小华的RTC外设中,有个RTC补偿寄存器,可以对外部32768Hz晶振的频率进行修正,可以使RTC运行精度更高。

这里分享一下个人对这个补偿值计算的一些理解,经过实测补偿效果还是很准确的。
RTC补偿寄存器描述如下(L196系列参考手册):
其中CR部分就是补偿值,对晶振的补偿范围可达-274.6~212.6ppm的。补偿步进0.96ppm。
此寄存器描述中,说明此寄存器是带有5位小数的补码形式。
并给出了以下取值实例:
此示例中,涉及到一个操作是“取2的补码”,在此实例中,需要了解两个概念才能完成运算。
一:关于补码
在计算机存储中,为了存储有符号数,所以有了补码的概念,具体原理可以参考网络其他原理性文章,这里就不再重复引用了。
关于补码,可以只记住以下两句话
1、 正数的补码是正数本身。(0也是)
2、 负数的补码,是其对应正数的取反加一。
二:如何取小数的补码
整数取二进制时,可以使用辗转相除法,一直除2并取余数即可。
而小数值取二进制时,需要使用“乘二取整”的方式,例如例子中对0.6651904取2的补码,由于需要取5位二进制小数,如下步骤操作
0.6651904*2 =1.3303808 -------取1
0.3303808*2 = 0.6607616-------取0
0.6607616*2 = 1.3215232-------取1
0.3215232*2 = 0.6430464-------取0
0.6430464*2 = 1.2860928-------取1
因此例子中的0.6651904转换为五位二进制是0.10101B,寄存器需要四位整数,即0000.10101B,最终写入值就是0000.10101 + 0001.00000 = 0001.10101B。
对于负数,取二的补码就是正数的取反加一的值,0000.10101取反+1即1111.01011。
最终写入值为1111.01011+ 0001.00000 = 0000.01011B
以上就是手册中描述的计算方法。
三:简化算法
可以注意到,正数取二进制时,每一BIT表示的就是2的N次方,即从最低位开始,表示的1,2,4,8,16,32……的个数。
而小数部分,表示的是2的-N次方,即从小数最高位开始,分别表示1/2,1/4,1/8,1/16….
我们寄存器的小数部分,只用到了5位小数,所以最低位表示的是1/32,即一个数字由多少个1/32组成。
因此在这种特定情况下,正数取2的补码,可以直接除1/32,也就是直接乘32,就是所要计算的2的补码。
例如例子中的0.6651904,不需要再一步步的乘二取整,直接乘32,得到21.2,其二进制数值就是10101B。
如果是负数,就直接取反加一即可。
在完整的计算步骤中,需要将ppm值进行* (2^15) / (10^6)处理再进行取补码的计算。
而我们之前已经把取补码的计算简化为*32。
所以此处可以合并计算为ppm值进行* (2^15) *32/ (10^6)
即 ppm*32768*32/1000000.
如果ppm为负数,就将结果进行取反+1即可。
因此,按照以上思路,将ppm转换为补偿寄存器的值可以按照以下代码进行转换
传入值为当前晶振的误差,单位为ppm。返回结果是可以直接写入寄存器的CR值。
uint32_tPpm_2_Compensation_Reg_standard(float ppm)
{
    uint32_t Result = 0;
    ppm *= 32768*32;
   
    Result = ppm / 1000000;
    if(ppm > 0) //正数
    {
        Result += 0x20;
    }
   
    else //负数,取反加1
    {
        Result = ((~Result) + 1) + 0x20;
    }
    return Result&0x1ff;
   
}

使用特权

评论回复
沙发
只是个新人-| | 2023-12-15 17:37 | 只看该作者
有需要技术支持  可以加我,超奈斯的**   V 13554256038

使用特权

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

本版积分规则

9

主题

81

帖子

0

粉丝