文章目录
- 一、RTC基础知识
- 1.1 RTC简介
- 1.2 RTC的晶振
- 二、stm32的RTC
- 2.1 RTC和后备寄存器
- 2.2 stm32 RTC结构框图及特性
- 三、stm32 RTC编程
- 2.1 RTC初始化
- 2.2 RTC控制程序
一、RTC基础知识
1.1 RTC简介
实时时钟的缩写是RTC(Real_Time Clock)。RTC 是集成电路,通常称为时钟芯片。
实时时钟芯片是日常生活中应用最为广泛的消费类电子产品之一。它为人们提供精确的实时时间,或者为电子系统提供精确的时间基准,目前实时时钟芯片大多采用精度较高的晶体振荡器作为时钟源。有些时钟芯片为了在主电源掉电时,还可以工作,需要外加电池供电。
RTC模块之所以具有实时时钟功能,是因为它内部维持了一个独立的定时器,通过配置,可以让它准确地每秒钟中断一次。但实际上,RTC就只是一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。其在掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。
1.2 RTC的晶振
任何实时时钟的核心都是晶振,晶振频率为32768 Hz 。它为分频计数器提供精确的与低功耗的实基信号。它可以用于产生秒、分、时、日等信息。为了确保时钟长期的准确性,晶振必须正常工作,不能够收到干扰。RTC的晶振又分为:外部晶振和内置晶振。
RTC的晶振频率为什么是32768Hz?
- 32768 Hz = 215 ,可以分频15次后得到1Hz的频率,1S的周期 ,实现秒计时。
- 经过工程师的经验总结32768 Hz,时钟最准确。
- 规范和统一。
二、stm32的RTC
2.1 RTC和后备寄存器
RTC电源
RTC和后备寄存器通过一个开关供电,在VDD有 效时该开关选择VDD供电,否则由VBAT引脚供电。
后备寄存器(10个16位的寄存器)可以用于在关闭VDD时,保存20个字节的用户应用数据。
RTC和后备寄存器不会被系统或电源复位源复位;当从待机模式唤醒时,也不会被复位。
RTC晶振
实时时钟具有一组连续运行的计数器,可以通过适当的软件提供日历时钟功能,还具有闹钟中断和阶段性中断功能。
RTC的驱动时钟可以是一个使用外部晶体的32.768kHz的振荡器、内部低功耗RC振荡器或高速的外部时钟经128分频。
为补偿天然晶体的偏差,可以通过输出一个512Hz的信号对RTC的时钟进行校准。
RTC具有一个32位的可编程计数器,使用比较寄存器可以进行长时间的测量。
有一个20位的预分频器用于时基时钟,默认情况下时钟为32.768kHz时,它将产生一个1秒长的时间基准。
RTC计时
- STM32的RTC只用一个32位计数器来计时,而不是用年月日时分秒的分组寄存器。
- 通过设置可以让这个计数器1秒加1,从0-0XFFFFFFFF大约可计时136年。
- 时间起点一般设置为1970-01-01 00:00:00(因现有函数如此定义,想更改需要重新编写时间换算函数。
如果要读当前的年月日时分秒,先读出32位RTC计数器值,然后以1970-01-01 00:00:00为起点, 加上计数器中的秒数,再换算成年月日时分秒,即可得出当前时间。
后备寄存器
2.2 stm32 RTC结构框图及特性
stm32的实时时钟RTC(real time clock)是一个独立的32位的定时器。stm32的RTC可以提供日历时钟,闹钟的功能。
RTC模块和时钟配置是在后备区域(下图灰色区域位后备区域)。只要后备区域提供电源,RCT便不会停止工作。通常会在后备区域提供一个纽扣电池保证RTC正常工作。
RTC_DIV寄存器、RTC_PRL寄存器是20位。RTC_CNT寄存器、RTC_ALR寄存器是32位。
- 3种时钟来源
常使用LSE作为时钟来源。因为215 = 32768,LSE=32.768K
RTC_DIV常配置为32768,对LSE时钟进行分频。分频后,频率就为1Hz,实现一秒记一次数。 - 可编程的32位的计数器
只能向上计数。
- 3个专门的可屏蔽中断:
闹钟中断还可以用来唤醒CPU,可以利用RTC实现为定时开机的功能。
闹钟中断还可以连接外部中断。 - 系统复位保护
除了RTC_PRL、 RTC_ALR、 RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。
RTC_PRL、 RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。
系统复位后,默认禁止访问后备寄存器和 RTC,防止对后备区域(BKP)的意外写操作。若想后备寄存器和RTC ,需使能PWR、BKP时钟,允许后备寄存器BKP访问。
三、stm32 RTC编程
2.1 RTC初始化
RTC初始化分为首次启动RTC初始化,普通启动RTC初始化。
注意,由于RTC时钟与众不同,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。
首次启动RTC初始化具体步骤如下: (RTC相关 库函数在stm32f10x rtc. c和stm32f10x_ rtc h文件中)
- 使能电源时钟和后备寄存器时钟,允许RTC后备寄存器写访问。
(PWR中有备用寄存器和RTC相关的电源,RTC使用到后备寄存器,所以要打开BKP)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE) ;
PWR_BackupAccessCmd(ENABLE) ;//允许后备寄存器访问 - 复位备份区域,开启外部低速振荡器并等待晶振稳定。
BKP_DeInit();//这个将导致RTC被复位,不用每次都调用这个
RCC_LSEConfig(RCC_LSE_ON) ;//打开外部低速振荡器
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); - 选择RTC时钟,并使能RTC,让RTC开始工作。
RCC_RTCCLKConfi g (RCC_RTCCLKSource_LSE) ;
RCC_RTCCLKCmd (ENABLE) ; - 开启RTC后,检查时钟同步,等待写操作完成。
RTC_WaitForSynchro();
RTC_WaitForLastTask(); - 设置RTC分频器,使RTC时钟为1Hz,等待写操作完成。
RTC_SetPrescaler(32767);//RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
RTC_WaitForLastTask(); - 设置RTC中断。(不需要中断可略)
RTC_ITConfig(RTC_IT_SEC, ENABLE);//秒中断
RTC_WaitForLastTask(); - 编写RTC中断服务函数。(不需要中断可略)
RTC_IRQHandler
FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG) ;
RTC_ClearITPendingBit(RTC_IT_SEC) ;
2.2 RTC控制程序
建立一个结构体来管理时间。