RTC简介
实时时钟是一个独立的定时器。
RTC模块拥有一组连续计数的计数器,在相应软件配置下,可 提供时钟日历的功能。
修改计数器的值可以重新设置系统当前的时间和日期。
RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒 后,RTC的设置和时间维持不变。
系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操 作。执行以下操作将使能对后备寄存器和RTC的访问:
● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟
● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。
主要特性
● 可编程的预分频系数:分频系数最高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
─ HSE时钟除以128;高速外部时钟 (HSE)这是以外部晶振作为时钟源,晶振频率可以在4MHz到16MHz之间选择,通常采用8MHz的晶振。
─ LSE振荡器时钟;(低速外部时钟 (LSE)以外部晶振作为时钟源,主要提供给实时时钟模块,通常采用32.768KHz的晶振)
─ LSI振荡器时钟;低速内部时钟 (LSI)由内部RC振荡器产生,也主要提供给实时时钟模块,频率大约为40KHz。
● 2个独立的复位类型: ─ APB1接口由系统复位;
─ RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位(详见6.1.3节)。
● 3个专门的可屏蔽中断:
─ 闹钟中断,用来产生一个软件可编程的闹钟中断。
─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。
─ 溢出中断,指示内部可编程计数器溢出并回转为0的状态。
结构图
简化的RTC框图
选择外部低数时钟
低速外部时钟 (LSE)
外接时钟频率为32.768 原因为2的15次方为它 将它分频15次为1秒
复位
-
系统复位://设置寄存器复位
- 当STM32微控制器执行硬复位或软复位时,RTC模块也会被复位。
- 系统复位可以由外部复位引脚、电源管理模块或软件命令触发。
- 系统复位后,RTC会重置到其默认状态,例如日历寄存器会被重置到1970年1月1日。
-
看门狗复位:
- 如果配置了窗口看门狗(WWDG)或独立看门狗(IWDG),当这些看门狗计数器达到预设的值时,也会触发RTC复位。
- 这些复位通常用于检测软件运行失控或系统故障。
-
掉电复位://外接电源电池断电
- 当电源电压低于RTC模块的复位阈值时,RTC模块可能会自动复位。
- 掉电复位通常用于防止在电源电压不足时,RTC模块的寄存器值被破坏。
RTC的寄存器
-
RTC_CRH(控制寄存器高):
- 用于配置RTC的预分频器、闹钟中断、秒中断和唤醒功能的使能。
-
RTC_CRL(控制寄存器低):
- 用于控制RTC的启动和停止,以及读取RTC的状态。
-
RTC_PRLH(预分频器加载寄存器高)和 RTC_PRLL(预分频器加载寄存器低):
- 用于配置RTC的预分频器,以确定RTC时钟的频率。
-
RTC_CNTLH(计数器寄存器高)和 RTC_CNTL(计数器寄存器低):
- 用于存储RTC的秒计数器值。
-
RTC_ALRH(闹钟寄存器高)和 RTC_ALRL(闹钟寄存器低):
- 用于配置RTC的闹钟时间。
-
RTC_DIVH(分频器寄存器高)和 RTC_DIVL(分频器寄存器低):
- 用于配置RTC的时钟分频器。
-
RTC_CR(日历寄存器):
- 用于存储当前的日期和星期信息。
-
RTC_TI(时间寄存器):
- 用于存储当前的时间信息,包括小时、分钟和秒。
-
RTC_BKPxR(后备寄存器):
- 用于存储后备电池供电的RTC时钟信息。
-
RTC_ISR(中断和状态寄存器):
- 用于读取RTC的中断标志和状态。
-
RTC_ICR(中断清除寄存器):
- 用于清除RTC的中断标志。
-
RTC_PRER(预分频器寄存器):
- 用于配置RTC的预分频器。
-
RTC_CNTH(计数器寄存器高)和 RTC_CNTL(计数器寄存器低):
- 用于存储RTC的秒计数器值。
-
RTC_ALRH(闹钟寄存器高)和 RTC_ALRL(闹钟寄存器低):
- 用于配置RTC的闹钟时间。
步骤
在STM32上设置RTC、读取RTC数据和写入RTC数据的基本步骤:
1.配置RTC时钟源
- 选择时钟源:通常选择低速外部时钟(LSE)作为RTC的时钟源,因为它是一个稳定的32.768kHz时钟。
- 使能时钟:通过编程RTC和后备域(RTC和后备寄存器时钟使能)相关的RCC(Reset and Clock Control)寄存器来使能RTC时钟。
2. 配置RTC
- 配置RTC初始化结构体:使用
RTC_InitTypeDef
结构体来配置RTC的参数,如小时格式(12小时制或24小时制)、日期格式等。 - 初始化RTC:调用
HAL_RTC_Init()
函数,将配置好的参数写入RTC相关的寄存器。
3. 设置时间
- 配置时间结构体:使用
RTC_TimeTypeDef
和RTC_DateTypeDef
结构体来设置时间和日期。 - 设置时间:调用
HAL_RTC_SetTime()
和HAL_RTC_SetDate()
函数来设置RTC的时间。
4. 读取时间
- 读取时间:调用
HAL_RTC_GetTime()
和HAL_RTC_GetDate()
函数来从RTC模块读取当前的时间和日期。
5. 写入数据
- 写入后备寄存器:STM32的RTC模块通常附带后备寄存器,可以在微控制器断电后保留数据。可以使用
HAL_RTCEx_BKUPWrite()
函数来写入数据到后备寄存器。
6. 读取数据
- 读取后备寄存器:使用
HAL_RTCEx_BKUPRead()
函数来从后备寄存器读取数据。
注意
当关闭RTC(实时时钟)模块时,日历功能通常不会更新。RTC模块需要保持运行,才能持续跟踪和更新时间。如果RTC被关闭,它将停止计时,因此日历信息也不会更新。
在某些情况下,即使RTC模块被软件“关闭”(即,不再通过软件更新或读取时间),只要RTC的电源(例如后备电池或超级电容)仍然连接,RTC硬件本身可能仍然在运行。这取决于具体的微控制器和其RTC模块的设计。但是,如果软件不再与RTC交互,那么即使RTC硬件在运行,系统也不会知道当前的时间或日期。
如果你想要在关闭RTC模块后保留日历信息,你需要在关闭之前将当前的时间信息存储到非易失性存储器中(如后备存储器或Flash),然后在重新启动或打开RTC时从这些存储器中恢复时间信息。这样,即使RTC在一段时间内没有运行,系统也可以恢复到最后存储的时间点,并继续从那里更新日历信息。