GD32F4系列 RTC使用外部低速晶振配置时钟,时间快慢问题

[复制链接]
2382|19
 楼主| 紫气东升 发表于 2022-2-18 17:41 | 显示全部楼层 |阅读模式
在上一次解决了使用外部低速晶振配置时钟遇到的无法同步问题之后,做了一次时间准确度测试。测试记录如下:
刚开始测试:2.15 周二 17:11:57  灯亮(没注意看时间,不过大概是这个时间,记得没有超过5点12分)
第一次闹钟:2.16 周三 17:11:57  灯灭
第二次闹钟:2.17 周四 17:11:52  灯亮
第三次闹钟:2.18 周五 17:11:47  灯灭
明天继续检测第四次闹钟时间,不过按照这个趋势,我猜测它的闹钟时间应该是17:11:42。
那么问题来了,不是说使用外部晶振时间精度很准的吗,看这个测试结果,每过一天(24h),时间就变快5S,这样算下来一个月时间偏差就有2.5分钟了。
我想请教一下各位大佬,这个时间偏差是正常的吗?如果正常那就这样了,如果不正常,有什么办法可以改进,尽量使时间更精确。

评论

今天第四次闹钟:2.19 周六 17:11:41 灯亮  发表于 2022-2-19 17:18
AnkerSong 发表于 2022-2-21 10:06 | 显示全部楼层
所有mcu的rtc时钟都是需要校准的。
手册里有描述。
AnkerSong 发表于 2022-2-21 10:37 | 显示全部楼层
你可以看一下rtc_coarse_calibration_config()函数
按照你每天多5s的速度算,粗校准寄存器RTC_COSC应该配置为:COSD=1,COSS=0x1D
 楼主| 紫气东升 发表于 2022-2-21 15:09 | 显示全部楼层
AnkerSong 发表于 2022-2-21 10:37
你可以看一下rtc_coarse_calibration_config()函数
按照你每天多5s的速度算,粗校准寄存器RTC_COSC应该配置 ...

好的,多谢指点,我试试看。这个函数是在启动外部晶振后开始用的吧?
rcu_osci_on(RCU_LXTAL);  //使用外部晶振32.768K
    rcu_osci_stab_wait(RCU_LXTAL);
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);  //配置RTC时钟源为外部晶振32.768K
    rtc_coarse_calibration_config(CALIB_DECREASE, 0x1D);  //对晶振进行粗校准
    prescaler_a = 0x7F;  //ck_apre频率 = RTC_CLOCK/(prescaler_a+1) = 32768/(127+1)=256HZ
    prescaler_s = 0xFF;  //ck_spre频率 = ck_apre/(prescaler_s+1) = 256/(255+1)=1HZ
    rcu_periph_clock_enable(RCU_RTC);  //使能RTC外设时钟
    rtc_register_sync_wait();
AnkerSong 发表于 2022-2-21 17:10 | 显示全部楼层
紫气东升 发表于 2022-2-21 15:09
好的,多谢指点,我试试看。这个函数是在启动外部晶振后开始用的吧?
rcu_osci_on(RCU_LXTAL);  //使用外 ...

可以。
需要注意的是,校准只是粗校。
晶振的频率会随着温度的变化而变化,也就是说如果外界温度变化,rtc时钟还是会有一定量的漂移。
如果需要非常精确的时间,建议使用温补晶振。
 楼主| 紫气东升 发表于 2022-2-23 09:13 | 显示全部楼层
AnkerSong 发表于 2022-2-21 17:10
可以。
需要注意的是,校准只是粗校。
晶振的频率会随着温度的变化而变化,也就是说如果外界温度变化,rt ...

大哥,经过测试。这样配置行不通,依然是没效果。我再放两天看看,不过大概率是不行的。
void rtc_pre_config(void)
{
    /* enable access to RTC registers in backup domain */
    rcu_periph_clock_enable(RCU_PMU);  //使能PMU电源管理单元时钟
    pmu_backup_write_enable();  //使能电源备份源,RTC需要此备份域
    rcu_bkp_reset_enable();
    rcu_bkp_reset_disable();

    rcu_osci_on(RCU_LXTAL);  //使用外部晶振32.768K
    rcu_osci_stab_wait(RCU_LXTAL);
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);  //配置RTC时钟源为外部晶振32.768K
    rtc_coarse_calibration_config(CALIB_DECREASE, 0x1D);  //对晶振进行粗校准
    prescaler_a = 0x7F;  //ck_apre频率 = RTC_CLOCK/(prescaler_a+1) = 32768/(127+1)=256HZ
    prescaler_s = 0xFF;  //ck_spre频率 = ck_apre/(prescaler_s+1) = 256/(255+1)=1HZ

    rcu_periph_clock_enable(RCU_RTC);  //使能RTC外设时钟
    rtc_register_sync_wait();
}
 楼主| 紫气东升 发表于 2022-2-23 09:20 | 显示全部楼层
既然理论上配置prescaler_s = 0xFF;为1HZ(1S)。实际上比1HZ大(也就是大于1S)。那我如果配置prescaler_s = 0x100;会不会好一点呢?
AnkerSong 发表于 2022-2-23 10:53 | 显示全部楼层
本帖最后由 AnkerSong 于 2022-2-23 11:04 编辑
紫气东升 发表于 2022-2-23 09:20
既然理论上配置prescaler_s = 0xFF;为1HZ(1S)。实际上比1HZ大(也就是大于1S)。那我如果配置prescaler_s = 0 ...

不行,粗校只有5位,上限就是0x1F。多看看手册呀兄弟。
————————————————
另外,我刚又看了一遍手册,一次粗校只持续64min,属于暴力校准。
你还是试一下数字平滑校准吧,具体的手册里有写,比较复杂,你研究研究~
 楼主| 紫气东升 发表于 2022-2-23 11:44 | 显示全部楼层
AnkerSong 发表于 2022-2-23 10:53
不行,粗校只有5位,上限就是0x1F。多看看手册呀兄弟。
————————————————
另外,我刚又看 ...

好的,我再看看。只不过手册我也看几遍了,看得不是太明白
AnkerSong 发表于 2022-2-23 13:46 | 显示全部楼层
紫气东升 发表于 2022-2-23 11:44
好的,我再看看。只不过手册我也看几遍了,看得不是太明白

直接看函数能简单一点。
rtc_smooth_calibration_config(RTC_CALIBRATION_WINDOW_32S,RTC_CALIBRATION_PLUS_RESET,0x3C);
然后你根据函数说明测算修改吧
tpgf 发表于 2022-3-3 11:09 | 显示全部楼层
这个有时差啊
guanjiaer 发表于 2022-3-3 11:17 | 显示全部楼层
仔细调整系数
heimaojingzhang 发表于 2022-3-3 11:21 | 显示全部楼层
还是直接看看函数吧
keaibukelian 发表于 2022-3-3 11:32 | 显示全部楼层
可以进行精校吗
labasi 发表于 2022-3-3 11:38 | 显示全部楼层
什么叫暴力校准啊
paotangsan 发表于 2022-3-3 11:50 | 显示全部楼层
和什么标准源做对比呢
 楼主| 紫气东升 发表于 2022-3-4 10:05 | 显示全部楼层
本帖最后由 紫气东升 于 2022-3-4 10:12 编辑
AnkerSong 发表于 2022-2-23 13:46
直接看函数能简单一点。
rtc_smooth_calibration_config(RTC_CALIBRATION_WINDOW_32S,RTC_CALIBRATION_PL ...

这样配置,测试结果也是没用,没变化
 楼主| 紫气东升 发表于 2022-3-4 10:13 | 显示全部楼层
paotangsan 发表于 2022-3-3 11:50
和什么标准源做对比呢

手机上的时间
 楼主| 紫气东升 发表于 2022-3-4 10:14 | 显示全部楼层

好像不行哦
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

97

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部