STM32的HAL库RTC使用CubeMX生成工程不丢日期

1、HAL库的RTC单纯的跑时间还是挺简单的,但是日期确实保存在RTC句柄下的一个结构体变量中,当掉电后日期便丢失了,重新上电初始化的话会在RTC初始化中强制赋值为0年1月1日,这就不爽了,于是通过查询资料终于解决了

2、先说硬件32内部RTC时钟可以选择LSI,但是LSI不属于备份域的范围,当掉电后,电池连接到VBAT引脚不能保证LSI工作,这样的话时钟就停止运行了,重新上电后还是掉电的时间,需要重新设置时间了,而且LSI的时钟频率30到60KHz,对应时钟来说也太不准了,而且对F103C8T6来说也不支持校准。如果不用于时间,而是短暂不精确的延时还是可以考虑的。因此还是要选LSE,这样的话就需要外部32.768晶振了,然后经典电路跨接两个电容中间接地。电容大小根据手册晶振阻抗30Ω,选择15pF就可以了。

3、说完硬件该软件了,先是CubeMX配置

 

 注意一下时钟选择LSE,数据格式跟你情况,我这里直接选择二进制了,也可以选择BCD格式,HAL自动转换也挺方便。配置好直接生成工程就行了。

4、因为main函数默认选择调用初始化函数,想自己写的话可以改一下CubeMx的配置

 

把这个√选上生成的程序就不会调用RTC初始化了 函数了,因为一旦调用RTC初始化函数就会重新配置RTC的备份域,设置时间日期,这对应掉电后重新上电会导致时间恢复为配置值,我看过一下这个博客采用了注释RTC初始化函数的方式,博主也说明了,没次重新生成工程时都需要重新注释掉初始化程序,我觉得很好解决啊

解决CUBEMX生成stm32f103xx RTC时钟掉电日期不保存的问题_C的世界的博客-CSDN博客_stm32rtc掉电不保存看

我先定义了两个变量用于保存时间和日期,其实可以不用定义的,因为在hrtc的句柄里都有这两个结构体。首先判断是否初始化还是利用电池供电时备份域的掉电保存功能,在初始化后写入一个非复位值这里我写成0x55,然后在初始化前读取备份域判断是否已经写入过0x55,表示已经初始化过,这个判断一定要放在 /* USER CODE BEGIN RTC_Init 1 */这个注释之后,不然CubeMx重新生成程序的话会覆盖到自己的辛苦成果。

当然CubeMX必须勾选这里,有点啰嗦了

 如果没有初始化则调用CubeMx生成的初始化函数,并在初始化后然后在

/* USER CODE BEGIN RTC_Init 2 */

这里写入BKP区域0x55,记录已初始化。

由于生成的初始化代码在if判断中,如果已经初始化过,就不会调用生成的代码,避免时间被重置为初始值,但同事也产生了一个问题,就是RTC句柄和备份域或者中断什么的都不会初始化,这就要自己来进行赋值了。RTC的时间是保存在RTC句柄hrtc中的DateToUpdate中 包括星期 月 日 年,重新上电后要从备份域中读取出来掉电前的日期恢复到DateToUpdate中

这样再获取时间时,日期就能正常连接上了

5、但是正常运行时要将最新的日期保存在备份域中,我这里时开启了秒中断,在中断里判断是否有日期更新,如果更新了就保存最新的到备份域

我使用的是备份域的2到5,1用于记录是否已经初始化。这样就可以保证掉电后时间正常走,上电后日期也不丢失了。

6、最后将rtc.h代码整体附上

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年9月11日
下一篇 2022年9月11日

相关推荐