
什么是RTC) z/ d& ?3 ~- w! `8 ]! g RTC (Real Time Clock):实时时钟 ; t# j/ w3 T# y# n RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。 ![]() 4 \9 E0 m7 U9 x0 m7 v2 { 在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。 RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高级指出也就在于掉电之后还可以正常运行。 - q/ P5 }) y4 T7 r 两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时( 12 或 24 小时制)、星期几、日期、月份和年份。此外,还可提供二进制格式的亚秒值。系统可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。 8 D( J5 ?# `' \1 Z1 K( ^3 ^; i 上电复位后,所有RTC寄存器都会受到保护,以防止可能的非正常写访问。2 }/ T4 ]* G9 L: z$ c & L. w' I7 G" a) J! n 无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内,RTC使不会停止工作。7 t% X% l" r+ X& H; l) I ' y6 ]3 h' t$ B8 r0 M RCT特征:, |6 S! K* ^) ] ● 可编程的预分频系数:分频系数高为220。# {/ j3 i) l" ~. \- Q$ N( P% C/ N& ? ● 32位的可编程计数器,可用于较长时间段的测量。, ]# d1 z$ t2 D# Q5 ^6 G0 I. s4 h ● 2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟 频率的四分之一以上)。 ● 可以选择以下三种RTC的时钟源:+ x0 N8 _( ?- d3 @! ?+ O ● HSE时钟除以128; ● LSE振荡器时钟; ● LSI振荡器时钟0 D6 W" n, b6 |7 t: \. f ● 2个独立的复位类型:/ o* B" j+ v6 c& C! Q ● APB1接口由系统复位; ● RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位 ● 3个专门的可屏蔽中断: ● 1.闹钟中断,用来产生一个软件可编程的闹钟中断。1 o4 o5 R0 \3 x! t/ q ● 2.秒中断,用来产生一个可编程的周期性中断信号(长可达1秒)。2 V1 x, t- S- M5 W; W% _7 D % T1 M0 l& c$ k0 a ● 3.溢出中断,指示内部可编程计数器溢出并回转为0的状态。2 [" q, z% v; n3 ^# G RTC时钟源:3 @' Z; X! ~/ C) q" { 三种不同的时钟源可被用来驱动系统时钟(SYSCLK): ● HSI振荡器时钟 ● HSE振荡器时钟 W! Y. T8 B8 m2 O9 `+ U ● PLL时钟1 ^" X9 J6 l1 k8 ~6 q4 p9 u $ B1 H) b: u, V: x 这些设备有以下2种二级时钟源:$ S& T7 W0 l3 j" q( K: y7 v, |7 E ● 40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTC。 RTC用于从停机/待机模式下自动唤醒系统。 ● 32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)。 # j2 n1 ?- L; L: M& L$ t$ N% N RTC原理框图& F* {3 {' ^$ s% h ![]() 6 X9 p) O- L; q7 m7 ~3 {( a RTC时钟的框图还是比较简单的,这里我们把他分成 两个部分: ' ]' x. f# k2 Z APB1 接口:用来和 APB1 总线相连。 此单元还包含一组 16 位寄存器,可通过 APB1 总线对其进行读写操作。APB1 接口由 APB1 总 线时钟驱动,用来与 APB1 总线连接。6 d7 E" e+ e8 w! ~! h ( A. l0 Q" p2 U! p7 E1 b) X- k 通过APB1接口可以访问RTC的相关寄存器(预分频值,计数器值,闹钟值)。 q5 P" X% D4 L" c" v RTC 核心接口:由一组可编程计数器组成,分成 两个主要模块 。 9 f! n* e2 a' Y9 \8 b ![]() 第一个模块是 RTC 的 预分频模块,它可编程产生 1 秒的 RTC 时间基准 TR_CLK。RTC 的预分频模块包含了一个 20 位的可编程分频器(RTC 预分频器)。如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个 TR_CLK 周期中 RTC 产生一个中断(秒中断)。 1 o! m! D, [( k& {# K3 C- ? ![]() - A3 {2 \6 u( E# m) d 第二个模块是一个 32 位的可编程计数器 (RTC_CNT),可被初始化为当前的系统时间,一个 32 位的时钟计数器,按秒钟计算,可以记 录 4294967296 秒,约合 136 年左右,作为一般应用,这已经是足够了的。5 k2 X# s/ {$ E7 `; u0 C, e 0 ^" ]4 G- d8 ^0 F [7 ~ RTC具体流程:# e0 g2 M( a$ k* q2 e7 w- Z, l RTCCLK经过RTC_DIV预分频,RTC_PRL设置预分频系数,然后得到TR_CLK时钟信号,我们一般设置其周期为1s,RTC_CNT计数器计数,假如1970设置为时间起点为0s,通过当前时间的秒数计算得到当前的时间。RTC_ALR是设置闹钟时间,RTC_CNT计数到RTC_ALR就会产生计数中断, RTC_Second为秒中断,用于刷新时间,2 X }. ^1 U7 @ RTC_Overflow是溢出中断。 RTC Alarm 控制开关机 RTC时钟选择使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作.所以RTC一般都时钟低速外部时钟LSE,频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现,所以被广泛应用到RTC模块.(在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式).: _+ t L6 E! P. p( ?' S RTC复位过程; `. X; M+ L. o" I" U 除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系统寄存器都由系统复位或电源复位进行异步复位。 RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器仅能通过备份域复位信号复位。 8 b5 Y; _4 V3 P' N3 C 系统复位后,禁止访问后备寄存器和RCT,防止对后卫区域(BKP)的意外写操作' X' f# W# K3 P) { 0 R+ x/ d. l5 F A4 B 读RTC寄存器, ?* L* D& y; w1 ]( { RTC内核完全独立于APB1接口,软件通过APB1接口对RTC相关寄存器访问。但是相关寄存器只在RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。所以软件必须先等待寄存器同步标志位(RTC_CRL的RSF位)被硬件置1才读。 配置RTC寄存器 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、8 |* d7 }8 I3 J. F( p& x' o RTC_CNT、RTC_ALR寄存器。' f3 i% J. ~2 l' l0 T0 N$ G 另外,对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询7 j. \7 T8 g) B" ?' T E RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是’1’ 时,才可以写入RTC寄存器。, y" H, l) ]# p0 k , R9 L. ~. F3 m: W RTC时钟源 RTC是一个独立的时钟源 ![]() $ U! I9 s: B. @% H7 ], O3 z$ g1 ? RTC寄存器 RTC控制寄存器 (RTC_CRH, RTC_CRL) }9 }, D9 R+ _% g1 p RTC预分频装载寄存器 (RTC_PRLH, RTC_PRLL) RTC预分频余数寄存器 (RTC_DIVH, RTC_DIVL)8 M6 w, g, |0 ^* b* L RTC计数器寄存器 (RTC_CNTH, RTC_CNTL) RTC闹钟寄存器 (RTC_ALRH ,RTC_ALRL) RTC控制寄存器高位——RTC_CRH 寄存器 ![]() & `: s$ f: }7 Q7 o8 i) I$ P 作用:配置3个专门的可屏蔽中断(溢出中断、闹钟中断、秒中断)使能。- O9 \" @6 J9 V! m% ~* \) v, _ 注意:系统复位后所有的中断被屏蔽,因此可通过写RTC寄存器来2 w/ k# p; U9 l 确保在初始化后没有挂起的中断请求。当外设正在完成前一次写操作时(标志位RTOFF=0),不 能对RTC_CRH寄存器进行写操作。 RTC控制寄存器低位——RTC_CRL 寄存器 : O4 B( ?- q0 h4 l) k( X% X ![]() 一般用到该寄存器的 3,4,5位, s( |8 |3 M5 D6 ?/ @ 1.第 3 位为寄存器同步标志位,我们在修改控制寄存器 RTC_CRH/CRL 之前,必须先判断该位,是否已经同步了,如果没有则等待同步 2.第 4 位为配置标位,在软件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的时候,必须先软件置位该位,以允许进入配置模式 3.第 5 位为 RTC 操作位,该位由硬件操作,软件只读。通过该位可以判断上次对 RTC 寄存器的操作是否完成,如果没有,我们必须等待上一次操作结束才能开始下一次,也就是判断RTOFF位是否置位。 三个位总结如下:' ?5 d h" m0 D$ z6 P; B ① 修改CRH/CRL寄存器,必须先判断RSF位,确定已经同步。' W' _* E: i8 \3 X- P+ {. ` ② 修改CNT,ALR,PRL的时候,必须先配置CNF位进入配置模式,修改完之后,设置CNF位为0退出配置模式 ③ **同时在对RTC相关寄存器写操作之前,必须判断上一 7 }5 A: V$ X; @. }$ D5 f( w: s: l ![]() 4 X* j6 S2 ]6 B) } RTC 预分频装载寄存器——(RTC_PRLH/RTC_PRLL) 寄存器 作用:配置 RTC 时钟的分频数,6 J; F% [2 O! F7 h% @9 F3 v2 f % e- H. K9 G* S7 l3 x, @ 比如我们使用外部 32.768K 的晶振作为时钟的输入频率,那么我们要设置这两个寄存器的值为 7FFFh(32767),就可获得周期为1秒钟的信号。/ V+ Z8 a; [2 c9 Z, O( f* e ![]() 8 b2 ~' E" B( B6 \5 c' ^, P RTC预分频器余数寄存器(RTC_DIVH、RTC_DIVL) 作用: 和他的名字一样,获得余数,也就是获取更精确的计时,比如:0.1s ,0.01 s等 ; x' `: `0 L' t2 A' L1 w1 L5 a 寄存器是只读寄存器,其值在RTC_PRL或RTC_CNT寄存器中的值发生改变后,由硬件重新装载。( n9 L1 G" d9 m& s" y% ]- d# e2 Y ![]() " y* ?' b0 l, r2 q: o, j' i$ H RTC 计数器寄存器——RTC_CNTX 寄存器, ^" ?! @1 h' f6 i 作用:存放计数器内的计数值。也就是用来记录时钟时间8 s) \& u8 s5 x7 O! m& A! ^ 该寄存器由 2 个 16 位的寄存器组成 RTC_CNTH 和 RTC_CNTL,总共 32 位,当进行读操作时,直接返回计数器内的计数值(系统时间)7 p8 ^5 J: q. ^/ R- ?1 ^1 Z ![]() # X7 k1 A. `# ]. k+ N' Y6 g RTC 计数器寄存器——RTC 闹钟寄存器(RTC_ALRH、RTC_ALRL). c1 ^2 F! \9 u' B! M% B+ D 作用: RTC时钟中断控制寄存器 w0 |! x Q8 o! S5 S: w! ^ 该寄存器也是由 2 个 16 位的寄存器组成 RTC_ALRH 和 RTC_ALRL,也就是32位,当可编程计数器的值与RTC_ALR中的32位值相等时,即触发一个闹钟事件,并且产生RTC闹钟中断。 - V! [% p9 T4 S; i i ![]() # W7 _+ _+ t) M: A7 [( b5 w! o BKP备份寄存器 备份寄存器是42个16位的寄存器。可用来存储84个字节数据。 它们处在备份区域,当VDD电源切断,仍然由VBAT维持供电。 ' l6 v5 u6 O9 N! O# {, b% K; Y 当系统在待机模式下被唤醒,或者系统复位或者电源复位,它们也不会复位。2 G( z, I. H- k- d, V O 执行以下操作将使能对后备寄存器和RTC访问:3 }; F$ b [7 f3 n2 q, \% K 设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备时钟。* c# Z- y+ x# |3 R: B( i2 n0 E 设置寄存器PWR_CR的DBP位,使能对RTC和后备寄存器的访问* P% e, C$ T( b( ^2 B' F ! y1 X6 p9 y; ~- f0 d+ |( O9 Z 一般用 BKP 来存储 RTC 的校验值或者记录一些重要的数据,8 \) B% N# {5 ~7 A& R# h, d. W4 m" p" p ![]() 配置RTC寄存器:" N t6 r- H5 a$ M 1.查询RTOFF位,知道RTOFF的值为1.- b" L) N+ y) B 7 s) M# s% ~0 v3 B 2.置CNF值为1,进入配置模式。+ H) p0 u! ]9 y8 w 3.对一个或者多个RTC寄存器进行写操作。 2 q* {$ q& }1 I 4.清除CNF标志位,退出配置模式。 & n7 ]3 o" |' G0 I I. o 5.查询RTOFF,直到RTOFF位变1,已确认写操作已经完成。9 w8 y7 E- D* G3 I0 n 仅当CNF标志位被清除时,写操作才能进行,这个操作至少需要3个RTCCLK周期。2 P t0 S; h/ X S/ ?( t RTC相关库函数 RTC时钟源和时钟操作函数:
RTC配置函数(预分频,计数值):9 g4 _& x4 j5 Q5 J# D5 ]
RTC中断设置函数:1 `$ r% a& O( ^6 B
RTC配置函数:: T, w! f3 N4 g7 \/ o: ~
RTC同步函数:! s) B( |" D# Y, S, D% J5 \
RTC相关状态位获取清除函数:4 v4 l3 e1 M! l
其他相关函数(BKP等)* p$ C# x, i0 @; |& ?
配置RTC步骤# a0 V% S t! ~" \$ { ①使能PWR和BKP时钟:. v7 `5 o( X! S9 `* m' O! m# l- C
② 使能后备寄存器访问:
③复位备份区域,开启外部低速振荡器。
④ 配置RTC时钟源,使能RTC时钟:. x# J3 g6 A6 S" t' B9 C: j* y4 b6 J0 Q
⑤ 设置RTC预分频系数:RTC_SetPrescaler();+ V, F" l, u- W' k# G3 i
⑥ 设置时间:RTC_SetCounter();
⑦开启相关中断(可选):
⑧编写中断服务函数:7 ~/ b8 S8 G& w" s8 Q1 H& c7 y
⑨部分操作要等待写操作完成和同步。
具体的代码,库函数写的太多了,我会用CubeMx配置下,用HAL库写一个例程,几十行就可以解决RTC, }* j$ K. r y " V) K) \3 {, D 4 z3 d X% [; V * m- {6 u3 Q9 Z+ w |
实战经验 | Keil工程使用NEAI库的异常问题
STM32 ISP IQTune:真正零门槛的免费ISP调整软件
【经验分享】STM32 新建基于STM32F40x 固件库的MDK5 工程
意法半导体MCU双供应链策略,打消中国客户后顾之忧
【经验分享】基于STM32使用HAL库实现USB组合设备CDC+MSC
2024意法半导体工业峰会:赋能智能电源和智能工业,构筑可持续未来
ST推出灵活、面向未来的智能电表通信解决方案,助力能源转型
意法半导体 x Qu-Bit Electronix:推动新一轮的数字声音合成革命
从STM32 MPU产品看嵌入式系统中微处理器的新变化
【Hot!】STM32全系列开发板都支持Arduino开发,你知道吗?