【STM32+cubemx】0009 HAL库开发:RTC实时时钟的使用、掉电时间保持

RTC (Real Time Clock)即实时时钟。它可以提供时钟、日历的功能;并且可以使用外部电池供电,在极低的功耗下保持计数,使得断电之后还能够计算时间,所以名为实时时钟。

STM32f103的RTC,本质上是一个32位的计数器,在断电后,由电池供电还能保持计数;要使用时间时,需要将计数器的值换算成日期和时间。

此外,stm32的RTC还具备后备存储区,可以利用电池供电,保存10个16bit的数据。

1)cubemx中配置RTC

我们在之前的串口中断工程上修改,以便于打印数值查看。

使用cubemx打开串口中断的工程,然后另存为RTC工程,增加如下设置,启用RTC,勾选时钟源、日历、以及RTC OUT:

(注意这里选择RTC OUT输出时,固定是PC13引脚,如果我们之前的工程中设置了PC13引脚,要先设为reset模式,再选RTC OUT)

设置RTC的初始时间:

(其实这里设置的用处不大,一般都要设置成当前的时间,所以一般都会在程序运行后,输入当前的时间再设置)

接着,设置RTC的时钟,切换到clock configuration 选项卡,如下设置,选择外部的低速时钟:

这里选择外部时钟是因为,内部的RC振荡器精度较低;而如果使用主时钟(高速时钟)分频后作为时钟源功耗较大;一般RTC要求掉电还能运行,需要低功耗。

设置完成后,就可以生成工程代码了。

2)keil中的程序编写

Keil中打开工程,在rtc.c文件中,我们可以看到RTC的初始时间是通过如下方式设置的,

有需要的时候,我们可以仿照这部分代码重新设置时间:

在main.c中添加如下代码,编译、下载、运行,可见右下角的串口打印信息:

这个程序先定义了两个结构体,用来作为保存日期和时间的临时变量;然后通过重定向后的串口打印输出。每秒钟打印一次,可以看到输出时间和日期能自动进位、更新。

3)RTC时间的掉电保持

通过上面的配置,我们已经可以设置RTC开始运行,但是,这个程序还很不实用;每次掉电、上电重启都会重新设置为初始时间;这完全不能发挥RTC的特点。

要想RTC在掉电后仍能继续计时、再次上电后还能保持准确的时间,需要软硬件两方面的支持。

首先,硬件上,VBAT引脚上必须连接电池,一般我们使用3V的纽扣电池,以使得断电后电池能为RTC供电,继续计时。

其次,软件上,需要修改HAL库代码,这里详细说说软件改写这一步。

Cubemx(5.10)生成的RTC HAL库代码,有不完善的地方,主要体现在日期的存储和时间的存储是分开的;日期的存储是在一个普通的RAM变量(就是HAL库中DateToUpdate这个全局变量)中,它每次在累计到满一天时,就会将日期存储(DateToUpdate)变量加1,然后将rtc的计数器清0;这样使用在不掉电时是没有什么问题的,但是一旦掉电,存储日期的变量(DateToUpdate)不能保持,会被置为初始值,而时间每次都是从rtc计数器中读取,这就导致掉电重启后,日期变成了2000/01/01,而时间还在正常继续累加

正因为这个每次日期进位的清rtc计数器操作,使得原本连续的rtc计数变得不连续,因而仅仅从rtc计数器中无法恢复时间。

有些网友的办法是,将日期值存在后备存储器中,这样掉电后再读取时可以恢复,但是如果掉电时间超过了一天,读回的日期会是前一天存储的,也不能保证完全正确。

比较彻底的解决办法是不用HAL库的时间设置和时间获取函数,把这套函数完全重写。主要的两个函数如下,就是设置时间和获取时间的函数,把日期和时间看作一个整体。

设置时间时,由日期和时间换算成秒,再写入rtc计数器:

获取时间时,读取rtc计数器,再由秒数换算成年月日时分秒:

实际上,rtc计数器有32位,每秒增1的话可以计时130多年不溢出,足够一般的使用了。

另外,还需要在MX_RTC_Init()函数中添加代码,如下:

这一段是读取后备存储区中的内容,然后对比是否与特定的RTC_unique_ID一致,如果不一致,则设置一个当前的时间初值,并将RTC_unique_ID写入后备存储区;如果一致,则说明初值已经被设置过,直接返回,不再执行HAL库函数中设置RTC时间的操作。

这样就设置完了,之后可以调用获取时间的函数了:

运行结果如下,可以看到中间断电了26分钟,有电池为VBAT供电,再次给系统加电时,时间和日期都能正确获取。

好了,这一节的内容基本讲完了,主要讲了RTC相关的知识,要想掉电后还能正确恢复时间,HAL库函数需要大改;此外,RTC的后备存储器,可以利用电池供电存储一些掉电需要保存的数据。

欢迎关注我的公众号,可留言“资料”获取相关资料和软件:

posted @ 2021-11-10 01:05  xiaobaibai_2021  阅读(3615)  评论(2编辑  收藏  举报