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

【经验分享】STM32F1之RTC

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:23
1.RTC是什么0 {3 ^. q7 o  g3 q! o( u
RTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。5 U- J  p6 g0 Z
( c2 V- z* L* D; l+ r' a& `' q
很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能。  f$ I+ v: O' t( P% ~

4 e& ~1 T9 ~( {6 C/ x6 b总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。# Z; K7 i! M& S8 d6 [, n
: u; ]- o/ N% i! Q" z# z$ R/ i4 ]! ^
实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。6 e3 x( q% }+ ?+ ~' m! I  a+ C+ a

  m( M0 {" d# Z- b8 J/ X( d" v  P- B9 \  K& \/ B4 ~  |6 d
2.RTC的优缺点
' P( \8 T. H$ \. ^; u+ C2 VRTC的作用是:可以提供稳定的时钟信号给后续电路用。主要功能有:时钟,日历,闹钟,周期性中断输出,32KHz时钟输出。- H2 ?% N% v! P) Y6 ^
( N6 p) \7 P& ?9 ~; t, Z0 L* h" ]
具有功耗低的优点,不能直接读出具体时间,只能读出秒数,根据秒数计算出当前时间。0 U! p9 M5 J# V' J& Q

) Z3 V- [5 j  r+ }主要性能指标
+ O7 Q3 I7 ?2 k: w# Z3 P7 ~8 E& W; e7 k$ _! E$ w
控制方式:二线制,三线,四线制。
5 N' H& D4 `- l
; t; q5 L, d% Q晶振:分内置晶振和外置晶振。
* |, L9 Y/ ~/ X, o# b- A( r" I$ X4 D8 m& V' W
耗流,时间微调范围,时间精度以及是否有TTF功能. s7 P  v+ n' l; C
/ `/ _$ y  m$ r$ g/ `
3.RTC使用方法- P  ^( H: P& F/ G
; Q- k5 i. i7 r/ i! d1 g6 Q
RTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。' C8 N, l' n1 d2 Y0 k$ E: a

. {( n8 j5 h( b$ v3 t
20160705225637308.png
8 [4 Z  D' R% M6 ~2 ~1 D; s, O  h3 Z- ^
  ~% |. x. f7 w6 _# Z& G
RTC核心模块! h0 u3 Y& [! I; L: n' l

6 w  [# c) E9 K5 |第一模块:预分频模块(可编程产生1S的RTC时间基准TR_CLK)20位的预分频器,在RTC_CR中设置相应允许位,会在TR_CLK周期中产生一个秒中断。
, w2 l- a# u5 g6 w: v4 C8 r7 g1 S" g$ ]4 g' J2 r
第二模块:32位计数器(可初始化当前系统时间); @" p: V" b- U+ `1 `
* }: J% q$ K. ]1 [- t" K
闹钟寄存器:
+ W! \4 p6 x3 f$ ]$ b+ `5 k
9 t. \! n2 J" z$ r" {系统按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
+ S' q/ Q( K& |  I
1 \8 P! e$ B. r8 v
! p! b1 f6 }4 V" T: `: b0 I* N由于RTC内核完全独立与APB1接口,软件只能通过APB1的接口访问RTC的预分频值、计数器值和闹钟值,相关的寄存器值是在APB1时钟进行重新同步的RTC上升沿被更新,所以在读取RTC寄存器曾经被禁止的APB1接口前,必须等待RTC_CRL寄存器的PSF位被置10 U3 y7 D% P( [3 o
. |6 P2 n& Q5 S# T* K

: R- L& B# H3 @1 C: y8 MRTC控制寄存器(控制中断用,秒中断)" ~' w8 y! q6 u5 k

5 b# X* ]4 x: M9 vRTC_CRL:
5 z3 i3 U: R3 r
' M' f% F* x1 O0位:进入秒中断后,可判断该位为1决定发生了中断,必须写0清除
1 j, l/ X4 q! [6 I0 f  W7 _( i- x
* n+ w- k. R4 E& i! x4 o. H# [3位:寄存器同步标志位,没有同步之前,不被允许修改RTC_CRT/CRL的值,必须先判断该位为1时,同步了。
& e  d. e  v/ Q1 @8 x: d1 b! o8 V2 d" r
4位:在修改RTC_CNT/RTC_ALR/RTC_PRL的值前,必须置该位为1,进入配置模式。1 H6 F+ H% e+ h& p& f

8 {( U0 F  V( }, K* u5位:RTC操作位,由硬件操作,软件只读,判断该位为1时,表示上一次操作已经完成,才可进行下一次操作。* a! S7 ?5 ]' `8 v
# ?' N( E. R4 W  K. J# W
0 `3 V( `: t& g2 W$ q
RTC_CRH:0-3位置1,允许溢出中断、闹钟中断、秒中断。
" _& m$ A( j' p; ]/ a1 k- L& I# n% p0 f9 E. w1 ?$ @# Y! b2 R9 ~( f
RTC预分频装在寄存器
" C6 [, X+ F8 e2 \
4 \4 e& a: ?9 l" B9 T4 T, S9 K他俩是配置RTC时钟分频系数的。
( A0 _1 Q. |' }1 E0 W: N+ J- K8 V: |) ^% z. g
TRC_PRLH:低4位有效,存放PRL的19-16位
/ I) a* p9 v% d1 ~& r
4 ]2 U2 w/ N6 r+ M; zTRC_PRLL:存放PRL的前16位  s- C+ |9 S3 O5 i7 p

8 d& H; g6 a% c( k+ Q" ?$ L- t
) _1 }- W& s8 h8 R  XRTC计数器寄存器RTC_CNT(2个16位寄存器组成,共32位RTC_CNTH、RTC_CNTL:用来存放秒钟值)# W! N+ K8 d; s

1 ^6 ~* y9 p. v! e* a+ A) G) t9 h0 F6 u) b! e' b3 `! F( a
RTC闹钟寄存器:(2个16位寄存器组成,共32位)
- T" m. m& S, Q* q" b* W* ~' H- l+ ~3 m# G* t
RTC_ALRH、RTC_ALRL:
( v  B8 q8 ^- ]4 m% ]- H% K7 M6 `2 z
  h" ^6 m$ K3 P! N用来记录闹钟产生的时间,当RTC_CNT与RTC_ALR的值相等时,则产生闹钟中断,条件是使能了中断且进入了寄存器的配置模式了。
/ A% A: s( @* ?( a3 o7 J
9 y8 T  ~1 A# x; c+ V+ }( A3 k备份寄存器(存储RTC相关信息,待机模式被唤醒等操作备份区域不会被复位). I: \$ S8 u! b, y& V% b

% N/ `( t- u+ Z5 ?& l执行如下操作对备份寄存器和RTC进行访问
' L) \1 b) O9 x3 x7 Q- L4 c& ^4 R
& a" S2 D" h! D- |; P1)设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟
# y% X7 f. C5 [1 W) S/ q& P
/ e6 G# V/ v) \3 M9 O2 w2)电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。" [9 |  g% C* @" n" y

, Y9 f% r3 \# e2 T$ i
2 V% }2 M. E) A/ E7 w1 L( P# ~- a4.使用步骤:0 Z) h7 ]* H& u! O% v) [

7 K/ j" g8 F" X5 q! ^% S0 K1 l1)因为RTC模块和时钟配置系统处于后备区域,这样做的好处是系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。所以首先需要判断备份区域是否为第一次设置,如果是,则进行RCC相关寄存器的设置,如果不是,则不需要配置。
( L3 I7 x: u& D) s' _! }2 N2 T) @3 m  i) F+ i
如何判断是否为第一次,那就在配置完成的最下面,向备份区域随便写一个数据,在开始配置的时候,去读一下备份区域的这个字节,如果存在,则已经配置了,如果不存在,则需要相关配置。
# a% `' J7 f( P: c& k$ U1 i2 ?; M+ y* V
接口函数BKP_ReadBackupRegister(uint16_t BKP_DR),入参函数可以是随便的BKP_DR其中一个寄存器,等到写的时候,也是写在这个寄存器中。
1 X7 f( u$ u4 c; m
7 J& Z( X2 h# w$ J1 \: `8 J2)执行如下操作对备份寄存器和RTC进行访问
, _1 D7 z5 ~, Y
( s8 t  f" ]& K2 D0 Z# S- j1 q- E# o; g; R/ a" v: ~9 }$ T+ C
a.设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟
2 r/ {( j' K1 o. O8 |
: I- p7 t; c3 Q. t8 |# P: uRCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1ENR_PWREN,ENABLE);2 ?' Y% n: E1 b  v

$ D+ p2 L  _6 Zb.电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。
, R+ G1 ~, o  p% S
2 G# T- |( U+ Y4 X: |后备区域可以维持系统复位或从待机模式唤醒后RTC的设置和时间不变在设置时间之前,需要取消备份区域写保护,以防止对备份区域意外写操作。# X3 l1 {8 l# e+ N4 @1 X( j

" V+ w* t* w; p; H" D' R! k2 bPWR_BackupAccessCmd(ENABLE);
& K. b0 O2 C) D- W" x' M- K  J# z% d8 H4 [" y
( G) ^# C- A' K& T

4 t( s8 }0 [. F, [3)在取消备份区域写保护之后,可以先对这个区域复位,以清除前面的设置。7 v* ^: X( X  b6 A" H
- h6 w  H- B& ~6 a- s0 Q
BKP_DeInit();
0 ~, ]8 {9 A% Z7 J. b* \3 _. k0 L2 M) r$ J; e- Y

  t" d4 p! t. ?# M/ ^0 N( k. v7 h! O+ Z$ J
4)备份区域控制寄存器RCC_BDCR
$ k5 c4 q( o  I( H' J% p1 [. \' }& [' ]2 K; ^- w
作用:RTC的时钟选择及使能设置。所以在操作RTC之前先应通过此寄存器选择RTC的时钟源。选择LSE时钟,因为LSE为外部低速时钟,比内部时钟稳定。
/ f7 `) X( M3 }# a  X( N) l- _3 j9 c0 B( F9 \9 v: p( }
RCC_LSEConfig(RCC_LSE_ON);8 T% j$ n8 @" B! U

1 a( z3 V& D; D+ a可以通过while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)接口判断晶振是否正常运行。) g( C. A) j9 h7 y

4 M% f4 f7 ?! p0 @. |; y' T% r3 b
5)开启RCC时钟5 m; |8 C/ N* g* N5 ?$ u6 X/ q2 x
7 t0 a4 t4 M1 R2 ^. j
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
! f5 L; x* z6 r8 I) ?1 j
2 U- z5 i+ ~% g, O/ ^; O/ o9 I  G6 F  K+ F; Z7 N6 H! M6 h
6)使能RTC时钟
' a- m% I4 e+ e1 ]7 E) e6 [1 h, M5 D* r6 c, d7 i) [' \
RCC_RTCCLKCmd(ENABLE);
5 N9 e/ z7 H9 K0 v+ f3 P' {* M, S7 c6 @9 ?

! M. f" ]# W, `1 w9 G! K  Q7)等待最近一次对 RTC 寄存器的写操作完成与RTC 寄存器同步完成(每对RTC寄存器进行一次操作,都要调用这些接口)
! N  j- v( n+ j0 }) _& x8 `
5 e: ]6 d% y& v0 IRTC_WaitForLastTask();9 [$ Y+ @& ?: i( [% o2 x
6 p- k# w( i' u" K; H3 ~: @
RTC_WaitForSynchro();: Z7 a  B3 f& i( U0 V
. R- Y3 d1 G, k2 b. l# u

3 J5 i/ L, Z: K3 ]5 j' s
" x8 j  B  }1 k( |& T8)使能 RTC 秒中断
) [) }0 C  |& v) T1 K' v
! S& i$ j2 c$ K) B8 E+ E' ORTC_ITConfig(RTC_IT_SEC,ENABLE);; F) R4 W- ^1 ^# s0 }
  B& V8 `+ v" \7 N5 n8 ~8 C! ]" A

/ x& z" P0 ^5 P7 X) U  ~, F
) r- X0 ^3 r2 u5 E! h$ [6 ?9 W9)设置 RTC 预分频的值4 L3 i& z5 f& N# ?2 [! b

2 ]! _5 E0 r3 t4 M% {RTC_SetPrescaler(32767);  
) y+ O" J1 d2 C
+ \# i7 ^" u8 k2 d( I关于STM32定时器怎么计算重装值和预分频' _5 X* B& _: B
分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,
; v6 N, i7 i6 n# F) z* i% E! ^! ]* }2 H0 I
表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。   / R. B/ Q' N. A1 p, B. `
! w' j; D/ T. A6 F% {
! a' I" I8 a( h
10)编写函数,设置想要让RTC从何时开始的时间,如2016年7月12日18点28分,要把这个时间从1970年1月1日0时0分0秒开始到此时的总的秒数计算出来。然后通过RTC_SetCounter();接口设置初始时间。; a" b6 z" \' ~  g7 b% Q
" W: k3 }* B9 I$ [
11)然后在RTC中断处理函数中,通过判断RTC中断类型,RTC_GetITStatus(RTC_IT_SEC)!=RESET,还要记得清除标志位RTC_ClearITPendingBit(RTC_IT_SEC);。在此中断函数中调用一个获取当前时间的接口(自己写),在此接口中调用RTC_GetCounter()官方接口,获取当前的总秒数,在把秒数计算出当前的时间。总的来说就是每秒进一次中断,中断中获取一次当前从寄存器中读出的秒数,再根据秒数把秒数计算出当前时间。
* m8 s2 U7 O5 j" P4 M# @2 z" ^
# i+ k5 V, e6 C; V
) [# Q8 \$ }/ W. b0 U/ Q: j
赞 收藏 评论0 发布时间:2021-11-29 22:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

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