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

【经验分享】STM32F1之RTC

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:23
1.RTC是什么
4 z7 k* D- z; o0 ^5 E9 T! J3 h# iRTC,英文全称:Real-time clock,中文名称:实时时钟,是指可以像时钟一様输出实际时间的电子设备,一般会是集成电路,因此也称为时钟芯片。
/ j& v5 c1 Z+ g- P; }1 J
9 X4 R, d3 ?1 L+ A% t很多CPU中都已集成RTC系统,且有许多独立的外接RTC芯片可用于实现RTC功能。
3 V, T1 F3 @" C! ?3 D/ A
, k" t3 {9 g5 ^; v: g总之,RTC只是个能靠电池维持运行的32位定时器,并不像实时时钟芯片,读出来就是年月日。
1 X% D  G6 p1 |) d+ L# _0 Y' M6 c
实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。* U% U( ]. e7 }

. W) O; F' M7 ~! E+ I# R: i( d% o4 V  `9 X0 o
2.RTC的优缺点- _; I8 ]* F! H/ r7 k
RTC的作用是:可以提供稳定的时钟信号给后续电路用。主要功能有:时钟,日历,闹钟,周期性中断输出,32KHz时钟输出。
" f: I5 ^7 \* b: n$ k8 U" Q! `1 R$ u, h) O
具有功耗低的优点,不能直接读出具体时间,只能读出秒数,根据秒数计算出当前时间。
, x. r& [) W* b0 ]  v  S9 g# @
$ E3 K6 H8 [9 A* C, D主要性能指标
4 E4 q. Z( A7 A, Y+ m% k: Q5 _+ T0 C/ M4 m
控制方式:二线制,三线,四线制。
# q- M- @; G" Q. {4 \2 q
8 u. o/ H) T  @/ Y- S1 w) Y晶振:分内置晶振和外置晶振。) v# Q+ k9 z( h  Z/ o! Q

7 g2 ?8 w6 L2 x% \耗流,时间微调范围,时间精度以及是否有TTF功能
- z) P0 N& C: q) V, N- [' B" U. j8 s! h7 N+ u& s
3.RTC使用方法
" R+ V1 o* G, p) T' F" t! d4 o% ?2 l4 i1 u" y" c% Z, `
RTC只是一个时钟,但与RTC相连的有两个系统时钟,一个是APB1接口的PCLK1另一个是RTC时钟。这样,RTC功能也就分为两个部分:第一部分,APB1接口部分,与APB1总线相连,MCU也就是通过这条总线对其进行读写操作。另一部分,RTC核,由一系列可编程计数器组成,这部分又再细分为两个组件:预分频模块与32位可编程计数器。预分频模块用来产生最长为1秒的RTC时间基准,而32位的可编程的计数器可被初始化为当前的系统时间。+ ~8 ~7 L! ~1 M, O# F. G, O

  v- B3 a& m8 e1 G
20160705225637308.png

2 D2 o" Q. D7 {# \% B7 v( x2 m
% Y$ v1 s- c6 O+ ]1 m7 V# N$ @; lRTC核心模块
% E3 d2 ]8 U% M+ M* a) ~, c
, b6 L+ n1 g8 W  {( L5 C第一模块:预分频模块(可编程产生1S的RTC时间基准TR_CLK)20位的预分频器,在RTC_CR中设置相应允许位,会在TR_CLK周期中产生一个秒中断。
$ u1 k/ ]8 y$ x0 }: w, C4 y, b; j. ]3 r9 q2 Z" N8 X, _
第二模块:32位计数器(可初始化当前系统时间)6 L! g6 R$ x& n$ [$ B' `  W9 }
) C, X) S8 g1 ~+ R. |
闹钟寄存器:
! x) E4 w4 e8 D) n" [" a& ]+ ^
! m" \" ~6 K+ H* v系统按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间比较,如果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。" }0 D2 Z$ a% S8 b( m
- _+ K. c7 F% U% i: s, R
% j6 m7 q; t' ^( H( \
由于RTC内核完全独立与APB1接口,软件只能通过APB1的接口访问RTC的预分频值、计数器值和闹钟值,相关的寄存器值是在APB1时钟进行重新同步的RTC上升沿被更新,所以在读取RTC寄存器曾经被禁止的APB1接口前,必须等待RTC_CRL寄存器的PSF位被置1; J# K3 L! e/ i
" t! A" R$ G8 }) ~% x" A! M3 ]
# T* e+ D2 j: m  u! C7 Y
RTC控制寄存器(控制中断用,秒中断)) {* z7 V8 U: @1 _, S3 L

; F' V: N- W. }# pRTC_CRL:/ ~- c1 X1 i( G, i
; ^2 Y+ C" F" U9 j9 k
0位:进入秒中断后,可判断该位为1决定发生了中断,必须写0清除. H# s+ C8 X. v% K

; k$ D  o' ^, U  _9 y& C. U3位:寄存器同步标志位,没有同步之前,不被允许修改RTC_CRT/CRL的值,必须先判断该位为1时,同步了。
$ X* a& B2 Y% ^5 a, c3 t# y2 G& H$ h: ^8 w7 P( G8 t: L# H
4位:在修改RTC_CNT/RTC_ALR/RTC_PRL的值前,必须置该位为1,进入配置模式。
1 T& Q* I! u' E, v: [
  w; ~1 P# c$ c9 D0 b5位:RTC操作位,由硬件操作,软件只读,判断该位为1时,表示上一次操作已经完成,才可进行下一次操作。
6 T  g' R2 d* z1 j! b
' r& e0 ?0 z" j4 q! {+ l/ w8 z! I5 B" ]  i) X: d
RTC_CRH:0-3位置1,允许溢出中断、闹钟中断、秒中断。
- m' G- z* K( Y& _9 S$ B" q7 d' Z7 ~( _1 Q& [
RTC预分频装在寄存器: M1 _. ?5 ?8 C0 @. t& P9 l" i! Q

5 x8 i9 c0 u/ X4 E: W, k8 h他俩是配置RTC时钟分频系数的。4 T1 b4 a4 p: k6 |. x1 ~
$ C0 ]1 v. \  D2 d
TRC_PRLH:低4位有效,存放PRL的19-16位$ d& N! A' |6 P! \4 d; V* I+ h
, D! D* m$ N! ?( F  Y
TRC_PRLL:存放PRL的前16位
2 V  G$ g- N7 X
7 }: c% T# H1 b+ ~6 V$ r1 R
2 \& `: O; G6 GRTC计数器寄存器RTC_CNT(2个16位寄存器组成,共32位RTC_CNTH、RTC_CNTL:用来存放秒钟值)
) z; ^9 H) p, l5 Q3 d" W
$ Z- R9 q3 U# Y- y/ E; o. _3 Z
( Y0 s* o- {" j8 l- e( zRTC闹钟寄存器:(2个16位寄存器组成,共32位)
" A1 P' m8 [6 G- ]% K, U4 q& a0 r% N4 q& [6 l: e
RTC_ALRH、RTC_ALRL:
% F7 g* ?7 y( F0 C& z( p  I# Y1 D
% b5 B" d+ r  o* r+ V用来记录闹钟产生的时间,当RTC_CNT与RTC_ALR的值相等时,则产生闹钟中断,条件是使能了中断且进入了寄存器的配置模式了。
$ e  K; X% q! ~+ e. m# V6 n  o5 J  e5 u4 J' v0 F
备份寄存器(存储RTC相关信息,待机模式被唤醒等操作备份区域不会被复位)  p% p8 V( e  H  n  I  o  i
$ U% p# P0 B6 W2 Q, w8 T
执行如下操作对备份寄存器和RTC进行访问: G& m6 b+ O+ s( f9 d
+ f, l% W! U2 r3 W5 D- M
1)设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟& x- @/ d5 c( |
% Q* n& w& P$ t
2)电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。7 F" _+ m+ z- a4 @- E, B
1 z' O# g3 O, d8 ^1 N/ w$ F- S

7 Z5 E! E, ^, h8 A9 d) m: i' l4.使用步骤:9 W" [0 Y1 y' P& A% I( k
* y5 b* v2 P  M% h
1)因为RTC模块和时钟配置系统处于后备区域,这样做的好处是系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。所以首先需要判断备份区域是否为第一次设置,如果是,则进行RCC相关寄存器的设置,如果不是,则不需要配置。6 H& N4 R& z) @$ l( M7 w/ D
- Y% j8 z$ l+ n3 b
如何判断是否为第一次,那就在配置完成的最下面,向备份区域随便写一个数据,在开始配置的时候,去读一下备份区域的这个字节,如果存在,则已经配置了,如果不存在,则需要相关配置。
; m, D8 y& Z8 y6 f0 y1 e' i; p- |% i" D: F1 q
接口函数BKP_ReadBackupRegister(uint16_t BKP_DR),入参函数可以是随便的BKP_DR其中一个寄存器,等到写的时候,也是写在这个寄存器中。" U1 s" E: O% J
  t3 `5 l& |4 w* V. L! J
2)执行如下操作对备份寄存器和RTC进行访问
7 X. t$ ~, \; J* K* Q. h, A: E8 ~8 U) c) N4 L
% K- A0 A% C, }3 X
a.设置寄存器RCC_APB1ENR的PWREN和BKPEN位打开电源和后备时钟3 I+ d8 F$ g5 S" h+ |
" t+ D6 m. s8 }* ~
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1ENR_PWREN,ENABLE);2 r$ Z2 T# Y5 }
5 y0 {, G- `4 }9 u" ~
b.电源后备寄存器(PWR_CR)的DBP位使能对后备寄存器和RTC的访问。
3 v! b4 L0 ~1 q5 n; F; M/ |6 t2 L* S3 P4 t) D' p
后备区域可以维持系统复位或从待机模式唤醒后RTC的设置和时间不变在设置时间之前,需要取消备份区域写保护,以防止对备份区域意外写操作。
+ m$ a8 \, D, Z  U2 l. p, k5 w6 U4 g0 S( P
PWR_BackupAccessCmd(ENABLE);
" d' ^1 L" x* Z) I* h: K- W9 O
, ]  K' m. x& B- A: a, h" A& u7 ^, ]0 J. z% |8 b$ g

( O  \, T( a4 p& l" t3)在取消备份区域写保护之后,可以先对这个区域复位,以清除前面的设置。" g4 c$ @; U- s. e

3 {" T% K5 }  T+ cBKP_DeInit();
8 x- _; O0 D3 i+ E: M1 d% p" R7 l4 H0 c5 E% u. d: H

8 K# t) r2 M  c
5 L& T6 z& p0 O# X5 F4)备份区域控制寄存器RCC_BDCR
2 v* `+ \& c, y2 E! B( [
5 I% Z6 x' ^+ o, o作用:RTC的时钟选择及使能设置。所以在操作RTC之前先应通过此寄存器选择RTC的时钟源。选择LSE时钟,因为LSE为外部低速时钟,比内部时钟稳定。
% d% G$ g& s' m4 n
9 D% k9 Y/ o6 H3 W! I5 V+ P- e0 HRCC_LSEConfig(RCC_LSE_ON);
3 E7 n1 c' a5 e+ T& f& J
  F& v3 S" f7 n: J1 n可以通过while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)接口判断晶振是否正常运行。/ e6 R9 }( P5 y/ g) I. c
) e- R6 I3 G9 |2 b0 P* {7 f

! z" h" _' a8 n7 C: `5)开启RCC时钟
( L1 r! y' x; w5 d5 p
' ]4 _" Y4 o6 ]2 |# v& aRCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
: Q6 Y, z' h6 u: m4 g, d3 i. d0 w% _6 r( g; T+ l8 u6 m% n  p) z
/ ~: g7 ]$ {) L+ y- X
6)使能RTC时钟' m2 Z8 W: ?/ `% M, k

( t% j! V' b; ~: nRCC_RTCCLKCmd(ENABLE);$ s/ ]$ j0 ?$ @& z' T( ^! q
( W& x: S" E! n+ k

% ]# Q6 I2 r0 l+ x  }" {/ q7)等待最近一次对 RTC 寄存器的写操作完成与RTC 寄存器同步完成(每对RTC寄存器进行一次操作,都要调用这些接口)- P- x1 Q$ u7 u# Y6 R2 N8 }

- P/ p( A+ z3 S/ e1 B# j0 j" j+ gRTC_WaitForLastTask();4 }" u3 R6 g/ u3 n8 G$ M6 A
0 v# s+ J/ S7 P( d  {* {
RTC_WaitForSynchro();/ ]: f* L3 Q+ i+ G* |+ Y6 t% q# C
- a/ Q9 J- X+ a5 p! L2 |% k

  o- i8 R  r4 b7 i% u$ h; \+ Q4 x4 {7 W3 o8 y: q/ @9 \2 w, A! F
8)使能 RTC 秒中断
5 p/ k; M+ o/ i. ]! p) F  R, l- w/ p/ G2 b. b1 b
RTC_ITConfig(RTC_IT_SEC,ENABLE);% B2 _6 o  W# q9 C

$ F/ V& X( ^1 C! t/ G  u5 E" w# [/ w, {% m. v
3 |- @& L" P0 t( |) S( g( _
9)设置 RTC 预分频的值0 E2 v' @- f: ?9 g; w  B$ c$ f
( g2 y5 ?2 b) W
RTC_SetPrescaler(32767);  
& G8 t% ~# t2 {7 d2 r% n- a
& x) K# w# [$ ^/ a$ R关于STM32定时器怎么计算重装值和预分频2 {1 Q* J! \5 G/ \0 i+ `
分频值是是指你将系统时钟的频率减小,假设时钟频率是72Mhz,然后分频值是7199,现在你的定时器值就是10kHz,6 q  x* K3 h, }8 s- b- y; N: g$ x0 x
8 w( Z1 D( h" H% S
表示每计一个数,然后过了1/(10^4)秒,然后你的重装值就是你的时间了,如果值是9999,就表示定时时间为1s。   # n5 Y  U; |; S3 C% @/ d( Z
1 @: [8 d1 a0 O

% d6 |" m* R, U% n10)编写函数,设置想要让RTC从何时开始的时间,如2016年7月12日18点28分,要把这个时间从1970年1月1日0时0分0秒开始到此时的总的秒数计算出来。然后通过RTC_SetCounter();接口设置初始时间。
7 j) R% K5 C/ S! |% y& n( |" r# p# q. z6 X, S
11)然后在RTC中断处理函数中,通过判断RTC中断类型,RTC_GetITStatus(RTC_IT_SEC)!=RESET,还要记得清除标志位RTC_ClearITPendingBit(RTC_IT_SEC);。在此中断函数中调用一个获取当前时间的接口(自己写),在此接口中调用RTC_GetCounter()官方接口,获取当前的总秒数,在把秒数计算出当前的时间。总的来说就是每秒进一次中断,中断中获取一次当前从寄存器中读出的秒数,再根据秒数把秒数计算出当前时间。% I( E# ?; D: M1 O: d
, ~0 t; P) T. F# ^- `
4 }  ^5 t2 L4 O/ O. G
收藏 评论0 发布时间:2021-11-29 22:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

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