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

【经验分享】STM32F1之RTC

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:23
1.RTC是什么
# H8 g5 ^2 f7 s# |7 u6 @RTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。
* \+ v3 q6 Z: |1 p$ I
0 P+ f" U" d0 l! [; ~+ m# W& p很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能。
5 \+ A. M' _+ b+ I* v  E! a% f- t) `+ _# ^7 u7 G3 Z. L! F
总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。8 w5 p  P, _  I$ }! I7 H4 Z
6 ]7 @! |* ?9 C3 u% b
实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。, v, \8 [0 i+ o# V

! b# ?* }2 R: L$ P! R1 g8 [9 |8 H1 a; B' }5 h
2.RTC的优缺点3 |# @' P7 j' Y2 z/ c
RTC的作用是:可以提供稳定的时钟信号给后续电路用。主要功能有:时钟,日历,闹钟,周期性中断输出,32KHz时钟输出。& b5 y( a  C+ ]

' V2 O. j' [6 V3 ~具有功耗低的优点,不能直接读出具体时间,只能读出秒数,根据秒数计算出当前时间。" v1 K" k" u( l6 T0 T. L' g

1 `1 W' S, k% k1 K主要性能指标
; S$ ]3 e5 ~. y' B2 h
% ]6 C5 Z5 w$ g, O8 [* _* G控制方式:二线制,三线,四线制。
! k% L& j1 n; r& l, z; e& A4 \5 x; D, U7 X3 F0 g% Z, D) K! \4 Q
晶振:分内置晶振和外置晶振。
) A* O* f% ~% X
5 \! h& y& t( K耗流,时间微调范围,时间精度以及是否有TTF功能
' f* @' }* m4 J3 ~  f; E3 c1 j, L9 |7 y! z
3.RTC使用方法
, w7 S, o, ]7 i
6 C: v* X5 M# ^- L" w+ c: v, sRTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。
+ _8 f6 L# _/ [) ], s; m1 H8 s, ?& s$ h4 L% O& h
20160705225637308.png
* Y2 A2 q0 _0 U5 Z6 x

5 Y3 k% Y; z8 @; b/ SRTC核心模块2 `4 G+ [  I" ]4 ~

! q; O. |+ |) t  c7 V: f2 p* w第一模块:预分频模块(可编程产生1S的RTC时间基准TR_CLK)20位的预分频器,在RTC_CR中设置相应允许位,会在TR_CLK周期中产生一个秒中断。
8 ?; y* R2 y* g, x3 A0 W3 S2 @6 S+ T7 R9 z5 q
第二模块:32位计数器(可初始化当前系统时间)
: w. }& P; ^1 ]# L! H' k8 u" R& U! L+ J
- f9 i. {; y; V) |闹钟寄存器:7 V$ w9 ~: _; V+ E+ h
' B6 S8 N3 W; ?2 `. b/ x  d
系统按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。
( b0 s! U$ N; u1 k3 t
# D# W/ P5 H& W7 O6 z# S. j) H: Z9 L
由于RTC内核完全独立与APB1接口,软件只能通过APB1的接口访问RTC的预分频值、计数器值和闹钟值,相关的寄存器值是在APB1时钟进行重新同步的RTC上升沿被更新,所以在读取RTC寄存器曾经被禁止的APB1接口前,必须等待RTC_CRL寄存器的PSF位被置1
! b- _: ]$ v& g' b  e1 I* Y! q: b& ^) ]2 w" g/ ?/ H6 }; ?0 X+ ~6 A# D

# `1 z6 j, S5 I( P! T" {8 @RTC控制寄存器(控制中断用,秒中断)# P7 w1 A* o; s, B! `

" Y* {2 z/ r% Z. G( k8 ]RTC_CRL:0 ^. U- V$ d0 S5 b8 l
0 W8 w: P% f- Z7 _6 R
0位:进入秒中断后,可判断该位为1决定发生了中断,必须写0清除
( z7 D6 P; x3 S# @; I( ^5 A$ T) p( j8 s7 ?
3位:寄存器同步标志位,没有同步之前,不被允许修改RTC_CRT/CRL的值,必须先判断该位为1时,同步了。) N: ^5 h% d7 p4 D- r
4 E: B# E& e4 ~' o$ \
4位:在修改RTC_CNT/RTC_ALR/RTC_PRL的值前,必须置该位为1,进入配置模式。* P! Y' e& x' B* a) _1 G6 k

8 o7 A( n2 I& A5位:RTC操作位,由硬件操作,软件只读,判断该位为1时,表示上一次操作已经完成,才可进行下一次操作。) A8 k% U* I/ ]' R
/ @9 I; j; `/ t) _9 A+ P- w1 B
! a- o- {1 W: t$ z( R% Y
RTC_CRH:0-3位置1,允许溢出中断、闹钟中断、秒中断。5 m# t) r2 m5 j2 L( O" S
6 p! c) j! q# M, z$ v$ u5 H
RTC预分频装在寄存器
0 o8 i, K( W( o: |6 h. Y* M* k/ C; y0 a
他俩是配置RTC时钟分频系数的。, N( P( m8 ^" X5 J3 A/ q  ~

* k4 {" W1 Z# P' o$ |0 Z3 R( q9 C: V. ]TRC_PRLH:低4位有效,存放PRL的19-16位- }* w, [" q: ]) _; G% C/ I

) i+ _% L0 }: x8 V/ ?; Y& oTRC_PRLL:存放PRL的前16位
% b2 m, X' [# g9 w$ U! Q8 I% a, z; v8 \7 G. k+ f1 E- J' P, _0 |4 H6 ~
& t, d- Q2 j+ u
RTC计数器寄存器RTC_CNT(2个16位寄存器组成,共32位RTC_CNTH、RTC_CNTL:用来存放秒钟值)
6 [* ?% }+ p5 M# }, ~' l* a$ o* F$ E" N* \, _  D. S. [
; F4 ?* a9 H( N- v
RTC闹钟寄存器:(2个16位寄存器组成,共32位)8 i3 H! I3 N) E) T" Z
7 ~3 z! r6 [: h2 H6 A9 B% O: i
RTC_ALRH、RTC_ALRL:( ~6 D# E" Q& P* }

; m7 g3 t  }$ |! K% m" t4 l用来记录闹钟产生的时间,当RTC_CNT与RTC_ALR的值相等时,则产生闹钟中断,条件是使能了中断且进入了寄存器的配置模式了。
. [- a2 ?/ U% W+ s& s
* D1 l7 Z% L: y2 F' ~5 n2 c备份寄存器(存储RTC相关信息,待机模式被唤醒等操作备份区域不会被复位)/ `+ m* X: z0 G. D6 q- i, n; t

" W3 Q* L7 \6 ?4 q0 D执行如下操作对备份寄存器和RTC进行访问
% L6 B5 [: V. s8 f+ Q, V3 {3 T6 y& h3 c/ m
1)设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟
+ h! M% P* k2 s# l0 t" o1 x9 p: K. _8 T1 f3 I' N2 N
2)电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。  U- e( A8 {' q
% f1 F9 p, \, ?" d7 c- c: P
6 V6 m6 \' V# Q
4.使用步骤:
. i! \; f! H( B+ S: W3 m' V( T0 J0 @8 k- ?
1)因为RTC模块和时钟配置系统处于后备区域,这样做的好处是系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。所以首先需要判断备份区域是否为第一次设置,如果是,则进行RCC相关寄存器的设置,如果不是,则不需要配置。
# O6 z/ q9 w/ f0 K' ^& ?+ w- _' b3 ^' v6 e" w& Z
如何判断是否为第一次,那就在配置完成的最下面,向备份区域随便写一个数据,在开始配置的时候,去读一下备份区域的这个字节,如果存在,则已经配置了,如果不存在,则需要相关配置。
, e4 G) T9 i/ y! A
( a5 e# |7 B1 V( w/ `; ?接口函数BKP_ReadBackupRegister(uint16_t BKP_DR),入参函数可以是随便的BKP_DR其中一个寄存器,等到写的时候,也是写在这个寄存器中。
$ B- H  M3 f( I' u6 f+ M& q
# G$ o4 L  U# k$ G) }! M1 [# {2)执行如下操作对备份寄存器和RTC进行访问
3 Y3 t/ @' b: d" V6 @$ C$ P' Q
  ~' k+ W: T$ T8 v# Q, i1 F7 k$ x: I- m+ R2 j& P. q
a.设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟+ d/ V- ~9 O8 b1 E2 f+ O' Q

! x( ^# e% V4 b4 ^RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1ENR_PWREN,ENABLE);
6 C! v; N: Q9 m1 J' i$ a7 Z) ], K1 F  Z9 s7 [/ Q1 y
b.电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。
7 D- ]9 A& R- G: n# g" @$ r6 h4 H7 y" U3 o0 L  T, m- j9 h
后备区域可以维持系统复位或从待机模式唤醒后RTC的设置和时间不变在设置时间之前,需要取消备份区域写保护,以防止对备份区域意外写操作。+ A; }. C) u' l
( w$ G; K0 v$ r1 N# E
PWR_BackupAccessCmd(ENABLE);
* \& F8 N2 G( r6 W, U/ z" j8 ?
: ?. r% \$ u; o5 K2 _3 G$ k" _' L" c

5 u( s, c1 r% v' R% w3)在取消备份区域写保护之后,可以先对这个区域复位,以清除前面的设置。2 m0 {8 P# i2 M- {( y
  E; f* L; f8 x: y. ^* o( b4 f7 j
BKP_DeInit();- o# D) d1 [6 }! z- Y6 s
# b; m# @4 V3 r7 C

/ i1 x2 c, ~5 E$ D) Y/ b+ c4 e9 |) k: n- k3 B8 y& b. P
4)备份区域控制寄存器RCC_BDCR
2 L3 Y: g( Y/ n) k
9 Q, n7 x1 t- z- G2 V作用:RTC的时钟选择及使能设置。所以在操作RTC之前先应通过此寄存器选择RTC的时钟源。选择LSE时钟,因为LSE为外部低速时钟,比内部时钟稳定。: Q7 N8 n- f& k
3 N( V# S0 D" v9 y- Q9 H/ R
RCC_LSEConfig(RCC_LSE_ON);
0 @0 D2 |! Z& N5 Q
  I( u& c1 b% x  Z' P$ T- r" u0 K) S可以通过while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)接口判断晶振是否正常运行。0 D% O! `. v9 m# Z7 C

) k+ K, F* e6 m# d6 ~* r6 W. {! z. x9 M' U# d* E6 r/ ^1 c1 U
5)开启RCC时钟
% ?, ~4 ^" p) L+ l7 E
# l3 f. T, u9 ^5 w6 eRCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);3 v. ^' L! ^6 d' Y' S/ g: Z- G

( V3 _* p# [* I! Y
/ G( A! p$ ?) L) z' E6)使能RTC时钟
. n7 V2 ~9 Z3 r. v* R  [& `
+ v4 f9 [8 _. v% RRCC_RTCCLKCmd(ENABLE);
2 a0 P0 Y: Y1 |. n4 j. G; @" J! t- [+ i: S" }- V. \3 y1 C; k% Y5 i

* _: f9 J7 n# g6 `7)等待最近一次对 RTC 寄存器的写操作完成与RTC 寄存器同步完成(每对RTC寄存器进行一次操作,都要调用这些接口)
2 Q+ s, v! P) f
5 X  O7 l) I  A& Z' yRTC_WaitForLastTask();' g! i, o1 ?  A

6 P6 [% |9 s. C$ C; n# JRTC_WaitForSynchro();" G" T/ i* z' u9 b( j

! o6 K4 I0 F3 y" f2 J/ D- S3 c- q9 T
9 B( j2 C: y2 N7 p
) I4 ^% C$ a0 j( I/ U8)使能 RTC 秒中断! `% F4 Y9 e% y5 S& t5 j
. P* g) B6 \7 t1 W; U$ P
RTC_ITConfig(RTC_IT_SEC,ENABLE);# f' J3 V6 V! q9 E$ a+ {, Y
2 @% S" `, r4 g! z* A

8 h& ]8 ], O; s0 f& x/ d5 D3 |4 f8 \8 y5 ^9 m$ k
9)设置 RTC 预分频的值
# k& t% T: a/ Y
6 p/ m. a. Z- T' D, E! x( s: Y" f# VRTC_SetPrescaler(32767);  
8 j" F2 S! [; @5 N. r8 Z
5 U/ K- z( r1 U! C2 c关于STM32定时器怎么计算重装值和预分频
  r  e+ {9 u4 X1 i9 \) Y, _5 U分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,
# y: T2 P: T5 ?& J
% `2 _; H5 F! \表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。   
7 L& t: Q3 G  B7 p9 r. R7 n
: W9 D: l- j/ h! d% b* R! X! E5 Y7 Y
- G' [" @  ?4 t8 H10)编写函数,设置想要让RTC从何时开始的时间,如2016年7月12日18点28分,要把这个时间从1970年1月1日0时0分0秒开始到此时的总的秒数计算出来。然后通过RTC_SetCounter();接口设置初始时间。
0 g# x# M+ R0 D- q+ \: L" y
& @3 `3 `- e3 r+ q11)然后在RTC中断处理函数中,通过判断RTC中断类型,RTC_GetITStatus(RTC_IT_SEC)!=RESET,还要记得清除标志位RTC_ClearITPendingBit(RTC_IT_SEC);。在此中断函数中调用一个获取当前时间的接口(自己写),在此接口中调用RTC_GetCounter()官方接口,获取当前的总秒数,在把秒数计算出当前的时间。总的来说就是每秒进一次中断,中断中获取一次当前从寄存器中读出的秒数,再根据秒数把秒数计算出当前时间。
8 l# u% Q) X/ o) x& v& k" L$ U/ D. X7 m" {9 L
, C% R! c# c2 I# F7 C
收藏 评论0 发布时间:2021-11-29 22:23

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版