RTC简介
实时时钟(RTC)是一个独立的定时器。STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。
RTC 模块和时钟配置系统(RCC_BDCR 寄存器)是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前, 先要 取消备份区域(BKP)写保护。
和通用定时器主要区别:
功能十分简单,只有定时功能(也可以触发中断),特殊之处在于断电之后仍可以独立运行,只要RTC备用电源供电,就可以一直运行。
两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。
上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。
无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。
RTC特征
编程的预分频系数:分频系数高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。
● 可以选择以下三种RTC的时钟源:
● HSE时钟除以128
● LSE振荡器时钟
● LSI振荡器时钟
● 2个独立的复位类型:
● APB1接口由系统复位;
● RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位
● 3个专门的可屏蔽中断:
● 1.闹钟中断,用来产生一个软件可编程的闹钟中断。
● 2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。
● 3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。
RTC原理
RTC工作原理图
RTC 由两个主要部分组成,
第一部分(APB1 接口)用来和 APB1 总线相连。此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总线时钟驱动,用来与 APB1 总线连接。
另一部分(RTC 核心)由一组可编程计数器组成,分成两个主要模块。第一个模块是 RTC 的预分频模块 ,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器 中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。第二个模块是一个 32 位的可编程计数器 ,可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记录 4294967296 秒,约合 136 年左右。
这里注意:
RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问,
但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。
所以软件必须先等待寄存器同步标志位被硬件置1才读(否则通常读到0)。
RTC相关寄存器
BKP备份寄存器
RTC控制寄存器 (RTC_CRH,RTC_CRL)
RTC预分频装载寄存器 (RTC_PRLH,RTC_PRLL)
RTC预分频余数寄存器 (RTC_DIVH,RTC_DIVL)
RTC计数器寄存器 (RTC_CNTH,RTC_CNTL)
RTC闹钟寄存器 (RTC_ALRH,RTC_ALRL)
BKP寄存器
控制寄存器 RTC_CRH
设置最低位为1,允许秒中断
控制寄存器 RTC_CRL
用到的是该寄存器的 0、3~5 这几个位,
第 0 位是秒钟标志位,我们在进入闹钟中断的时候,通过判断这位来决定是不是发生了秒钟中断。然后必须通过软件将该位清零(写0)。
第 3 位为寄存器同步标志位,我们在修改控制寄存器 RTC_CRH/CRL 之前,必须先判断该位,是否已经同步了,如果没有则等待同步,在没同步的情况下修改 RTC_CRH/CRL 的值是不行的。
第 4 位为配置标位,在软件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的时候,必须先软件置位该位,以允许进入配置模式。
第 5 位为 RTC 操作位,该位由硬件操作,软件只读。通过该位可以判断上次对 RTC 寄存器的操作是否完成,如果没有,我们必须等待上一次操作结束才能开始下一次操作。
预分频装载寄存器 RTC_PRLH
用来配置 RTC 时钟的分频数,如使用外部 32.768K 的晶振作为时钟的输入频率,则设置这两个寄存器的值为 32767,以得到一秒钟的计数频率
预分频装载寄存器 RTC_PRLH
预分频器余数寄存器( RTC_DIVH 和 RTC_DIVL)
这两个寄存器的作用就是用来获得 比秒钟更为准确的时钟 ,比如可以得到 0.1 秒,或者 0.01 秒等。该寄存器的值自减的,用于保存还需要多少时钟周期获得一个秒信号。在一次秒钟更新后,由硬件重新装载。
计数器寄存器 RTC_CNT
用来记录秒钟值(一般情况下),在修改这个寄存器的时候要先进入配置模式。
闹钟寄存器( RTC_ALRH 和 RTC_ALRL)
用来标记闹钟产生的时间(以秒为单位),如果 RTC_CNT 的值与 RTC_ALR 的值相等,并使能了中断的话,会产生一个闹钟中断。该寄存器的修改也要进入配置模式才能进行。
配置RTC寄存器
这里注意RTC时钟选择:
使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响.所以RTC一般都使用时钟低速外部时钟LSE,频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,容易实现
RTC相关库函数
/*RTC时钟源和时钟源操作函数*/
void RCC_RTCCLKConfig(uint32_t CLKSource);//时钟源选择
void RCC_RTCCL