你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F1之RTC

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:23
1.RTC是什么
3 C, h  P, ^# p) l$ }3 M2 JRTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。, ^5 P2 F0 v+ i; m
6 a" N" Z& O0 Y; q2 d! n
很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能。* g8 V) ]& J% T. e/ [$ G* ^
" ~2 C. T' }; V5 A) q
总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。
4 O. b" y3 E1 y2 H  X+ g
- z6 k. \! B6 C+ ~" u7 }' _# }( r实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。4 i! }2 {' l; X
4 M  q( S* g4 J# B$ S+ J  P, o+ G8 t

8 D0 s$ N2 X9 H: u2.RTC的优缺点
: K/ l7 K: Z1 h( y. M& W& L4 y( RRTC的作用是:可以提供稳定的时钟信号给后续电路用。主要功能有:时钟,日历,闹钟,周期性中断输出,32KHz时钟输出。
2 R" f- Y8 R+ y# l% |* i+ M5 [- w& }7 Y: ^3 o' f
具有功耗低的优点,不能直接读出具体时间,只能读出秒数,根据秒数计算出当前时间。
# d8 Y* V, _( x) n9 S  q" ]6 d6 ^4 r/ G4 U' Y1 T
主要性能指标
" j$ X0 x% m! ~. q8 F. g" y1 [
/ K( y9 }. v* Z+ U) P* w& G1 ~* w控制方式:二线制,三线,四线制。& b+ u( D% @+ i, @
, e) ~/ V0 p5 }( u
晶振:分内置晶振和外置晶振。
1 [' S- k7 ^0 h/ P
' F+ I4 ?) o/ Z5 J( I* i* |8 N耗流,时间微调范围,时间精度以及是否有TTF功能' p5 A% M- Z# R( H
  o0 F- b3 E. M! K/ e
3.RTC使用方法- L3 v& O9 R) D; \- X: h
6 c+ z5 n0 U& `
RTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。0 g8 C/ [" W* U5 M) W& ?, @. n
- O  U1 b$ r; V, ^- _* e+ }
20160705225637308.png
/ C/ T1 A% z4 R: h

7 h  d! E0 [5 O8 A# Y" g  t/ hRTC核心模块  |9 U' N/ G# v0 `( P6 P, w& I5 Y
( l5 M* c$ w+ _: h3 I
第一模块:预分频模块(可编程产生1S的RTC时间基准TR_CLK)20位的预分频器,在RTC_CR中设置相应允许位,会在TR_CLK周期中产生一个秒中断。1 V7 W/ L( J4 S
9 W+ a/ I! E- w" i' R
第二模块:32位计数器(可初始化当前系统时间)1 P9 T* s; D! `& v
$ U* e6 B5 Q( h# J- s* w
闹钟寄存器:3 e8 K4 h' G5 a# D6 [* \
; d7 H1 N; p( G* C
系统按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
/ n5 I/ t# ?/ L! R+ m/ e
& e9 U+ T" @( V" v& `4 V
, H- g+ X; v3 c  R) m3 q由于RTC内核完全独立与APB1接口,软件只能通过APB1的接口访问RTC的预分频值、计数器值和闹钟值,相关的寄存器值是在APB1时钟进行重新同步的RTC上升沿被更新,所以在读取RTC寄存器曾经被禁止的APB1接口前,必须等待RTC_CRL寄存器的PSF位被置16 e. F5 t( N$ a- ]( t- Y6 J  y9 e
! k6 x0 z0 P: W7 c. [! a
& U+ c5 W4 L  v: d  w" W
RTC控制寄存器(控制中断用,秒中断)$ O# H) X$ t& d) V* P

. F4 c; W. g) n9 TRTC_CRL:0 \) _7 F# f. `$ }

' I4 W) l0 j+ F6 V# R1 m0位:进入秒中断后,可判断该位为1决定发生了中断,必须写0清除
' x9 `' _( q6 Q9 L" w: I% u6 B4 U" Y
3位:寄存器同步标志位,没有同步之前,不被允许修改RTC_CRT/CRL的值,必须先判断该位为1时,同步了。
2 M2 Y# U, s1 W& P* e) I4 i8 c
) n: O& B7 k& J, h4 }) s4位:在修改RTC_CNT/RTC_ALR/RTC_PRL的值前,必须置该位为1,进入配置模式。7 V+ ?- i0 I% S2 P

6 r4 Y$ m0 m# P( }& j( g/ i& C0 L5位:RTC操作位,由硬件操作,软件只读,判断该位为1时,表示上一次操作已经完成,才可进行下一次操作。
& C( q& h* P4 B7 e- O* r9 K
- E# ]6 S% _2 e- A( L3 S; j$ T+ R! H0 k9 ^7 j4 [  e
RTC_CRH:0-3位置1,允许溢出中断、闹钟中断、秒中断。
3 s; C  W% K) D2 l4 e( o
1 w6 Y- K& H" X5 O; T7 H7 F+ VRTC预分频装在寄存器
  x# v$ B' j  _0 z5 o- F; i, {; Z! z0 {7 N$ j4 P7 O6 E. r" Z9 m
他俩是配置RTC时钟分频系数的。
( U6 T$ L/ F4 W3 p& p2 X: l( F
: C- o# o$ m" F3 A4 mTRC_PRLH:低4位有效,存放PRL的19-16位) D4 {" ?& W$ v* A* W

  G5 {, ?" K$ v3 O  I/ CTRC_PRLL:存放PRL的前16位
1 T! j% _0 E+ N4 M8 k
! E7 I, M% H' v, N# Q6 d3 d. y! [) `" m! J' m* ]4 g" L
RTC计数器寄存器RTC_CNT(2个16位寄存器组成,共32位RTC_CNTH、RTC_CNTL:用来存放秒钟值)! F- T- y' h: C0 X) q9 R7 X
: e) a6 ~) ~8 \4 V7 y2 t

" [, }$ m6 }% ?RTC闹钟寄存器:(2个16位寄存器组成,共32位)* b8 m4 ^* R1 L+ R- c; ?
9 q7 V+ E' s! }: Q" \/ N
RTC_ALRH、RTC_ALRL:
; u. a; ~" P! J) v/ G
# e& Y$ G! R6 S& b5 V用来记录闹钟产生的时间,当RTC_CNT与RTC_ALR的值相等时,则产生闹钟中断,条件是使能了中断且进入了寄存器的配置模式了。
2 r  @5 A- u1 R5 N0 b8 g2 _& {" }5 e; I6 Z9 i+ ?+ C( b
备份寄存器(存储RTC相关信息,待机模式被唤醒等操作备份区域不会被复位)
1 O: {3 _2 _  v, d+ T- b8 @8 ?  P& ~6 {9 t. F; Q
执行如下操作对备份寄存器和RTC进行访问8 L; a% s9 L) I* q# O
. c5 C6 H- D+ G6 R* e: `
1)设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟+ k9 h7 C- Z: V
* g8 ], L% |+ \. w
2)电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。
" A- Q/ a$ ^' p; P
' |1 d5 U! `: P7 k$ ~9 b
9 F% q2 B/ U; }  V7 [2 D0 }0 Y4.使用步骤:
: Y( U5 u8 z, Q9 n3 n: I: H' n, c* A2 `* k
1)因为RTC模块和时钟配置系统处于后备区域,这样做的好处是系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。所以首先需要判断备份区域是否为第一次设置,如果是,则进行RCC相关寄存器的设置,如果不是,则不需要配置。  m! R7 }) K+ p( Q3 h
; b  W. w, D6 ~* K. f: d# y
如何判断是否为第一次,那就在配置完成的最下面,向备份区域随便写一个数据,在开始配置的时候,去读一下备份区域的这个字节,如果存在,则已经配置了,如果不存在,则需要相关配置。$ V2 v3 H' H8 A8 D! `# N; x7 F
3 n# O( C9 V. f( i, c) K8 Z
接口函数BKP_ReadBackupRegister(uint16_t BKP_DR),入参函数可以是随便的BKP_DR其中一个寄存器,等到写的时候,也是写在这个寄存器中。
+ ?5 [2 J3 Z' h
9 M7 L; ]- d: a" s% z$ t6 ]9 x4 V2)执行如下操作对备份寄存器和RTC进行访问
5 H" N" o) }+ x4 S, E# G! T3 I: d3 S6 ?

0 d1 e. k! e- t$ pa.设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟
, c2 f& N( e* D; D4 t& H8 y5 {1 B/ @9 E/ a8 W" Y
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1ENR_PWREN,ENABLE);6 j- v: K& ^+ c6 K
8 V6 f6 l1 o9 P9 ~
b.电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。
; U1 V5 I3 ?) v
7 X. v0 D' C! |& A7 q后备区域可以维持系统复位或从待机模式唤醒后RTC的设置和时间不变在设置时间之前,需要取消备份区域写保护,以防止对备份区域意外写操作。
+ A& r# N9 _; T
8 Y$ N) E* D7 J& yPWR_BackupAccessCmd(ENABLE);
/ I$ @0 R0 M- o7 h/ L+ C% L, Y. |
: w. u7 K* Y+ K  Q7 x/ o/ D

& }' e' F" w1 c( ?, ~3)在取消备份区域写保护之后,可以先对这个区域复位,以清除前面的设置。1 O7 o- O% W% V0 D6 H2 F5 u$ k
: `$ j+ d# B: x, \
BKP_DeInit();
9 D5 C* `& S. b( l, D* }9 K& _/ Z: ?1 x1 s

5 W, O+ @0 O! @8 }' n* h) p7 u/ }3 s' s2 ~3 t0 c
4)备份区域控制寄存器RCC_BDCR
3 `7 ^; j8 r) w8 D3 o2 \6 x; s/ W3 r( G" D8 J! f
作用:RTC的时钟选择及使能设置。所以在操作RTC之前先应通过此寄存器选择RTC的时钟源。选择LSE时钟,因为LSE为外部低速时钟,比内部时钟稳定。
9 Z6 Q+ F2 ^& ~5 b9 P* ?" h8 D7 l2 L7 l" F2 n3 C
RCC_LSEConfig(RCC_LSE_ON);" @: j0 O: V4 B: H7 g# w, C
2 ~: x& N! M+ g4 S$ z% V
可以通过while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)接口判断晶振是否正常运行。
5 e  {1 X+ {7 {0 Q* \# e+ O. _! [/ R2 q4 O

5 Z( x3 L8 b- G6 J( s) Z5)开启RCC时钟
* w- E6 O: [$ b" T, x5 W% S6 ^9 r
  i, [: Y0 z' |) \: m* _" d+ }, {( kRCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);/ D  Z$ p# G$ O
' ?# C$ G" V( E) c/ T% @
% ^9 E' [1 N8 |: n4 s1 w, \
6)使能RTC时钟0 u, }2 q3 V$ \- q) J9 o: x
( q9 P0 k, V  b* O" ?0 z
RCC_RTCCLKCmd(ENABLE);
% ]; Q2 \/ h; u2 a1 U
2 T8 d# ~) [' @1 n( C" K& W& f7 W6 Z6 M2 ~1 J5 c  C
7)等待最近一次对 RTC 寄存器的写操作完成与RTC 寄存器同步完成(每对RTC寄存器进行一次操作,都要调用这些接口)
  c9 _$ k4 f3 B
7 p, N+ f# k4 x5 p4 I% q9 xRTC_WaitForLastTask();7 _; b  ]. }! ]7 f# G, J1 k' `
5 z3 h! M" ?6 Z& ~3 F
RTC_WaitForSynchro();
# \  a3 J! N8 k* }' p' t2 T
* _6 a, A+ |- i4 [% r% S$ L  H. k# c# F
1 B. u. X6 l( F  r
8)使能 RTC 秒中断
7 h+ E4 j- A, t2 E' s( |: h# B6 W
* y+ w, X: ?" Z) U% NRTC_ITConfig(RTC_IT_SEC,ENABLE);
* F* L1 u6 j8 R9 q& z" N( N
+ C6 k7 K5 A" r% [- Y5 Z4 |& Z
) Q& w1 e& U& Z9 e# o; ]4 I6 D  W. X; g+ H3 H3 s
9)设置 RTC 预分频的值! {/ s7 {5 p+ v" }2 b' ]) F  s
' e. @6 I5 |, p( y5 |& S4 L
RTC_SetPrescaler(32767);  
( M6 D* ~$ }5 c/ T) W+ K
4 t' a/ O  R$ X关于STM32定时器怎么计算重装值和预分频4 ~1 [* m( {. p6 S+ V+ _
分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,& x% B, S: {* h) J' c2 p" a% D3 f0 E- h

5 v9 p" v7 y* w' U0 Q' R表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。   0 c4 M7 s3 M; ]

  O" u9 w% U. J% D: {/ Y6 v) d
$ s# l( ]$ C0 |  k10)编写函数,设置想要让RTC从何时开始的时间,如2016年7月12日18点28分,要把这个时间从1970年1月1日0时0分0秒开始到此时的总的秒数计算出来。然后通过RTC_SetCounter();接口设置初始时间。
; r8 m$ o8 C6 [5 q4 }- P+ @  T0 x2 y3 \: N+ h
11)然后在RTC中断处理函数中,通过判断RTC中断类型,RTC_GetITStatus(RTC_IT_SEC)!=RESET,还要记得清除标志位RTC_ClearITPendingBit(RTC_IT_SEC);。在此中断函数中调用一个获取当前时间的接口(自己写),在此接口中调用RTC_GetCounter()官方接口,获取当前的总秒数,在把秒数计算出当前的时间。总的来说就是每秒进一次中断,中断中获取一次当前从寄存器中读出的秒数,再根据秒数把秒数计算出当前时间。1 i# S. W2 N/ ~- H; ~, V

) I9 k" Y$ M* O! R, a2 O5 \( |4 h6 ]" L$ ?% {6 d, s
收藏 评论0 发布时间:2021-11-29 22:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版