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

【经验分享】STM32F1之RTC

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:23
1.RTC是什么
0 i# p) B, W: z4 F& y7 lRTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。
9 P: e% Q) {9 e# d& T; m; B- A1 I* A6 ^- R* N& p9 b5 T9 j
很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能。. [8 Y' W7 n+ ?& a3 f) C! V
) Q& E0 a. G1 A3 G: {* Z
总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。; k- M2 i, Y3 l8 i3 z

; j* b) ?6 f2 C3 W5 b实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。8 s2 G+ g! n' x' L
/ V- V/ n0 ~" n. h

6 i7 X5 N1 n* f  L2 H# ?2.RTC的优缺点
  ~1 f9 I) N; M8 y5 i; e$ ]2 @, dRTC的作用是:可以提供稳定的时钟信号给后续电路用。主要功能有:时钟,日历,闹钟,周期性中断输出,32KHz时钟输出。- `) h- p# z' q8 ]
# x1 ?$ m% z9 _8 |' i& r8 r
具有功耗低的优点,不能直接读出具体时间,只能读出秒数,根据秒数计算出当前时间。  e) i% s$ [5 Q$ x

1 n6 j& a% U- J7 F主要性能指标& I4 v( u3 B' n# X2 [

* i+ `& }$ _4 K; `  K$ C' O% O控制方式:二线制,三线,四线制。! {9 H6 W* z0 q8 f

7 Q6 g' q1 @3 K晶振:分内置晶振和外置晶振。  u+ b/ W8 t$ A% g. A3 k
4 Z& l# [( \- \7 f- D
耗流,时间微调范围,时间精度以及是否有TTF功能3 g. f+ l4 x& @: B

# J1 L; N- [( o% L3.RTC使用方法
0 D& |* i* v8 \/ V( [
" @  e& j, {% ]RTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。" Y0 P+ |5 Q0 n, E. I. S
) d. z4 ^9 o* ]2 V
20160705225637308.png
1 y6 u8 Z  ~# c' V: k; c
, C2 d  e* O# J+ d! X8 u/ x6 n  _
RTC核心模块
1 w$ a& v+ v! `; p2 `$ L* \# }( I5 I( M
第一模块:预分频模块(可编程产生1S的RTC时间基准TR_CLK)20位的预分频器,在RTC_CR中设置相应允许位,会在TR_CLK周期中产生一个秒中断。6 E1 O/ I: s6 z

" _) N( a; @! H. Y2 d) d6 S" ]第二模块:32位计数器(可初始化当前系统时间)
" h: a, h" f" Q3 g7 E
& u+ D- d$ b' h9 t闹钟寄存器:
: o& E9 @) k" U0 `7 a1 o; f8 x5 f* W7 l6 u/ L7 L
系统按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
0 |4 M$ m8 l; R2 o& L& ]) ]7 h  Q. W5 j, i2 ~" ^
7 d. i7 U& A& o1 o  V
由于RTC内核完全独立与APB1接口,软件只能通过APB1的接口访问RTC的预分频值、计数器值和闹钟值,相关的寄存器值是在APB1时钟进行重新同步的RTC上升沿被更新,所以在读取RTC寄存器曾经被禁止的APB1接口前,必须等待RTC_CRL寄存器的PSF位被置1
' E4 N- v. ?3 E( k9 A  f
8 R% B  |6 W, w2 C: e! _5 M5 k: b- n
0 b  H' Z$ W/ ~# r0 _: e, z# mRTC控制寄存器(控制中断用,秒中断)& Y# U8 s' u+ I: U2 d; o. m
; g; N  Q2 g7 B# _$ `0 c5 O. C8 @9 T* A
RTC_CRL:3 P2 d+ V, t  L8 ]* O( z3 n" T

. l6 A% ]8 b7 J+ X' D* V. R0位:进入秒中断后,可判断该位为1决定发生了中断,必须写0清除
; p8 ?$ Z2 p/ k  m6 g. ^+ z8 \' D/ ^* w
3位:寄存器同步标志位,没有同步之前,不被允许修改RTC_CRT/CRL的值,必须先判断该位为1时,同步了。6 {6 Z. M! {* Q6 ?8 h3 ^- j+ s; u2 D6 O

" t$ M+ q" f8 v( L/ n( ]4位:在修改RTC_CNT/RTC_ALR/RTC_PRL的值前,必须置该位为1,进入配置模式。
" k4 `6 P& D" Y
+ f! f) ?" P0 K* d1 L3 }( V' [; }5位:RTC操作位,由硬件操作,软件只读,判断该位为1时,表示上一次操作已经完成,才可进行下一次操作。( P! C; O+ ?) P% v
% L) f% V+ i+ S# q  y
4 x6 }% k+ r6 ^9 q
RTC_CRH:0-3位置1,允许溢出中断、闹钟中断、秒中断。( ]- h% M9 F! e0 {, }7 E/ x
; X; G* Q3 B5 C( \
RTC预分频装在寄存器' e7 \- x- J; a0 E# J- ~# `
; E5 ]+ C- ?' O& Y
他俩是配置RTC时钟分频系数的。
% L: c) i! p" b9 n3 M4 m' k8 E6 C% p2 m4 Z& O) K, L& e
TRC_PRLH:低4位有效,存放PRL的19-16位
6 p6 @# G4 d! @# V7 B* q9 Q
; ~* ]) T% _5 }( vTRC_PRLL:存放PRL的前16位
. J2 O( w9 C. w( g5 z; L" C: m  H0 Z/ ~3 x
7 n' Z1 s1 F3 t$ E" y+ f3 S
RTC计数器寄存器RTC_CNT(2个16位寄存器组成,共32位RTC_CNTH、RTC_CNTL:用来存放秒钟值); u9 j! Y: ^3 `$ y3 B. r
* B/ r# I, J& T
0 q! \" Z" [; K8 x* g4 j8 X
RTC闹钟寄存器:(2个16位寄存器组成,共32位)6 C; P* K/ n4 a* L$ Y- ~' J

7 M$ ~* |; g$ j, n8 nRTC_ALRH、RTC_ALRL:( a/ f  ]: m# J" V& x2 r

* y4 S6 @* ?" l& M6 {用来记录闹钟产生的时间,当RTC_CNT与RTC_ALR的值相等时,则产生闹钟中断,条件是使能了中断且进入了寄存器的配置模式了。! m  Z! l+ s: w7 n5 y3 n
5 ]2 g3 v* Y& H! q9 v. L' F
备份寄存器(存储RTC相关信息,待机模式被唤醒等操作备份区域不会被复位)" H3 a: s, h, `& v! h9 d

) W# R5 M, D# S执行如下操作对备份寄存器和RTC进行访问8 q' j( v( N" b  Y

. y* K! E( P/ e  B! D4 m' L5 s1)设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟" |9 f! w* T, N7 m3 D
9 M- A# |: ?5 Y5 U. q# P, B  x
2)电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。, \' s5 f2 ^1 x; x" _4 F3 f

8 k  B4 C" ^" E0 b5 b" @4 D
! B* p2 M4 `- s* I; M& d4.使用步骤:
4 N0 p( P, B# M' A% d; B; u: V/ Q/ z, S" `2 C+ t
1)因为RTC模块和时钟配置系统处于后备区域,这样做的好处是系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。所以首先需要判断备份区域是否为第一次设置,如果是,则进行RCC相关寄存器的设置,如果不是,则不需要配置。$ V7 F- b; \. ^; ^
; Q/ z& M" P: J" D
如何判断是否为第一次,那就在配置完成的最下面,向备份区域随便写一个数据,在开始配置的时候,去读一下备份区域的这个字节,如果存在,则已经配置了,如果不存在,则需要相关配置。
( Y6 G) T0 ^; ?( z/ ~7 a2 p& W$ m( r
接口函数BKP_ReadBackupRegister(uint16_t BKP_DR),入参函数可以是随便的BKP_DR其中一个寄存器,等到写的时候,也是写在这个寄存器中。" O" e0 {; W! ]) S; E8 `- g2 i, @
. m1 o) _4 X& r! N1 x% T# g
2)执行如下操作对备份寄存器和RTC进行访问
6 v2 p/ ]" X/ R: f0 a" p, x2 I, c' ]/ I8 {3 c& k& E

$ V, [7 ?9 D+ I- X4 ra.设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟3 q( S" K$ A2 A, m$ @! g$ m. `! }
2 |/ u. D$ l4 ?9 r9 E5 J2 f
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1ENR_PWREN,ENABLE);7 l$ x1 E3 S  s3 A8 c. N

7 B, O  i" N; l! d. Eb.电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。6 ^7 L: p* i& E, i8 x

9 p+ ]+ m* B6 [  x  w* F3 l后备区域可以维持系统复位或从待机模式唤醒后RTC的设置和时间不变在设置时间之前,需要取消备份区域写保护,以防止对备份区域意外写操作。& W% x  @0 A. \; h; L! H  I# B+ l$ o
6 i2 y2 q& c4 z
PWR_BackupAccessCmd(ENABLE);. j$ P% @* {  h/ b
1 d% t  O7 d: O9 j" A9 F: h8 a

% s( ]( }; Q8 P5 d9 O& n! m
( l: v& Z; t& H! s3)在取消备份区域写保护之后,可以先对这个区域复位,以清除前面的设置。5 y; A! C' g, R! Q( n$ D
2 o. f$ m0 q( c5 F7 ?8 c
BKP_DeInit();5 W  |( P4 q& e3 ]

9 o+ T7 s; V8 A: W, f
5 z+ A6 o. V: b' F  A- U# O- O* D3 G5 i* q5 A/ \; x
4)备份区域控制寄存器RCC_BDCR
0 ^6 C0 Q8 Q% U+ M
: T7 c9 k+ Q3 r0 ?) s作用:RTC的时钟选择及使能设置。所以在操作RTC之前先应通过此寄存器选择RTC的时钟源。选择LSE时钟,因为LSE为外部低速时钟,比内部时钟稳定。
3 ?- y5 K1 c9 E: o8 v
+ Q9 Y: E0 A/ o/ fRCC_LSEConfig(RCC_LSE_ON);2 M2 e8 J/ J' S! a
5 ^( j) E/ z' ?/ c
可以通过while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)接口判断晶振是否正常运行。5 J# R3 [' l; ]/ R7 l- }; S

3 K' V. ]* G2 n8 T7 R9 _8 e6 u* f4 G9 j6 p* q% c, ^! s
5)开启RCC时钟( k4 _6 a7 b% U! j" U8 P

4 N: o" f; K1 i3 v# y3 u$ XRCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
0 L: ~- ?- _9 Z: h. v$ f5 m$ M, {; m' E

% B$ Z( |  o1 Y6 ]! P6)使能RTC时钟8 ]) c$ K6 v7 x/ ?9 }

: S* J, z/ }3 X1 ~4 }% N" ERCC_RTCCLKCmd(ENABLE);
" B( J9 z% S+ }. X+ J6 u
4 {  y. S# c4 z/ k% u3 d% t, O% y3 N
  U9 Y$ y( X$ _6 \: m7)等待最近一次对 RTC 寄存器的写操作完成与RTC 寄存器同步完成(每对RTC寄存器进行一次操作,都要调用这些接口)
$ i3 ^! R( e$ @; s" M# e
  l4 ]1 i; c/ ~( s& |8 f# `7 cRTC_WaitForLastTask();& D' q* `6 r  n" r8 h; }, E
1 f0 [# d4 ?, T- c
RTC_WaitForSynchro();
; c( u* Z& E4 `) D9 d0 a  K" J4 F

3 ~# A8 s% ?5 `/ `2 h6 p% B' ~& K2 j& r
8)使能 RTC 秒中断
& {4 ^/ y1 b; ^$ @' M4 l& f
3 h2 _# w( O1 o' B+ A" d; ^RTC_ITConfig(RTC_IT_SEC,ENABLE);0 V* Y( y1 r) a- N) E1 g
  G. |: l2 I; s# L/ ]9 {% w' k0 Y
6 H" n  _$ F' D+ U) v" }5 W" b) D
+ p6 V8 D% y9 }1 `' \- r
9)设置 RTC 预分频的值5 j& `( p) E# g# E# o7 R

; Z8 {8 v+ ]9 R. ]. Z4 X2 R7 TRTC_SetPrescaler(32767);  0 t8 H" I0 ?2 _- A7 G9 ], N: |$ M
: w, s  t* }  y: Y8 j
关于STM32定时器怎么计算重装值和预分频
( \+ E! {" `; I分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,
: ^1 {2 ^+ p7 i. Q8 \. R
" x* r$ \& j; z  F! s9 o: |! c2 |+ G表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。   
" `7 Z/ c& Q, }2 [
7 Y7 h( V4 v# {
" Q2 M7 q, b/ M( l/ |% }/ ], H10)编写函数,设置想要让RTC从何时开始的时间,如2016年7月12日18点28分,要把这个时间从1970年1月1日0时0分0秒开始到此时的总的秒数计算出来。然后通过RTC_SetCounter();接口设置初始时间。- L( G/ d3 N2 k( t/ \2 x2 q

% z, L' M# T4 F6 t( }2 G# @% u11)然后在RTC中断处理函数中,通过判断RTC中断类型,RTC_GetITStatus(RTC_IT_SEC)!=RESET,还要记得清除标志位RTC_ClearITPendingBit(RTC_IT_SEC);。在此中断函数中调用一个获取当前时间的接口(自己写),在此接口中调用RTC_GetCounter()官方接口,获取当前的总秒数,在把秒数计算出当前的时间。总的来说就是每秒进一次中断,中断中获取一次当前从寄存器中读出的秒数,再根据秒数把秒数计算出当前时间。# h+ j/ D' A' Q" q1 D0 j3 [
1 x1 t  X. q' I! b7 }

/ k! K4 S: ]  y+ E# K& ]2 A
赞 收藏 评论0 发布时间:2021-11-29 22:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版