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

[STM32 ] RTC 实时时钟的系统时间维护

[复制链接]
STMCU-管管 发布时间:2020-12-4 14:27
[STM32 ] RTC 实时时钟的系统时间维护

% F! ~* _' n7 ^% n6 _0 d+ |/ T+ k

' M/ k+ f& @  pSTM32内部带有RTC时钟,可以使用内部LSI和外部晶振LSE提供时钟源。
7 V4 m9 L2 C; Q8 }) _9 G; p( M+ w7 s% S7 Q- `: m7 }: b

# [% f' H7 M# `" m* Z  c% hLSI:单片机内部的晶振,受外部环境影响比较大,比如温度等因素;大概40Khz左右;
9 s$ S# h/ w  O/ h% J0 D, l
/ m& p1 D' n/ J3 h/ d  ~( c
" L% E: d8 B4 P- G" K- D% _& {
LSE:外接32.768KHz的晶振,比较稳定;
: w: I- I. r+ w! k* b0 E' V- \" r" Q3 w
; D+ L' ^5 ?8 z9 F9 W  F* q1 j! O
软件可配置选择时钟源,可判断识别是否起振。
6 f. u; c( b4 q6 C2 N  |. W
/ c# Y9 G$ z7 f9 }驱动:% x. P1 \# s2 d- d5 V
5 ]) {( f; Z- p% [. m* O
5 l9 I5 W4 n, N
1、首先要启动对应的时钟0 ~* T. i6 }0 e( {6 n% {1 K

' n8 P9 k% e0 B" z6 b
4 |- g% j# u1 g: o. Z
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);3 ?: D$ L* |0 r( |6 C, A0 @
" M$ x: i, i$ f3 j$ c  g7 ]

* d- g4 ~* A6 W% B7 q+ M. o: A2、使能RTC功能) e4 X1 D. ?, ]7 C+ t8 N) P: E

2 d& e) g% b# `9 r+ E/ A9 o7 g

- S8 B8 X9 i1 b9 n/ O  y5 B2 S$ vPWR_BackupAccessCmd(ENABLE);
( J. S# i1 a1 s" W; m' d$ o- p' E0 r* u' e6 T
! l; [6 I4 {( w: e6 I1 Z) ^
3、配置时钟" {* t2 S" ]8 n: O/ H8 V

- r: m# z7 b- w. g
. i) t  D, K: Z- M4 t# b; {+ Q" }
RCC_LSICmd(ENABLE);    //内部晶振
$ i0 P: m6 p2 T0 b$ O; \; ^( w# I# [8 H0 C: F0 p

& R9 K* ~; O% f8 H1 a% A6 r, V) v4 b4 ]RCC_LSECmd(ENABLE);    //外部晶振
- L: Q/ r  l& ?: E. u3 i8 r: J7 F4 n" Y; p" y8 W. ^# `5 j* }+ g

6 G8 D0 j$ c, |6 }( K1 D5 |读取LSE状态3 a- c. Q. W( b/ F# G! a
0 g' D  r8 g: R) j4 x, c
9 [, ^0 ^" Q: V# i+ I
RCC_GetFlagStatus(RCC_FLAG_LSERDY) : x( j0 D5 Q, b+ t$ g
0 i4 S3 V7 M/ t, u* @

. [$ B% X6 M% y( e( U读取LSI状态
& f: K6 y3 P$ S1 E6 B1 j
& _9 A, h3 J) Y& N% P

+ B2 ?/ x: D: F: vRCC_GetFlagStatus(RCC_FLAG_LSIRDY)
- n. ^; G( L7 {- k" _3 d) @) I  F
- e1 p1 N0 K$ S
4、操作RTC所有寄存器之前需要先确定总线为空闲才能操作成功;; P6 }! e+ d% T9 x0 z
. [. H9 v( O' w' ?9 H" H9 S
0 r) I0 h, r1 V: o
RTC_WaitForSynchro();//等待上一个指令执行完成;6 ~1 d# K; F. @* ]3 V$ L# M
9 z0 v6 E% W" H' p* F0 j0 o3 e  s9 l

" ?( f6 s' ~1 H- m: R% N+ `5、初始化配置属性* D5 D, Q' B5 D' e2 x# _
& W* k4 b7 A# H- w' V0 _
! _* a) d! D: g
        //软件对时钟进行校准,HSE 按照32.768KHZ接入,公式如下:& k' P9 c3 Q1 }  l7 U  j: @

6 A5 x$ H6 w7 l

8 F: H; @5 g5 s5 p9 d+ L       uwAsynchPrediv = 0xFF4 n8 p5 Y0 Y/ y' k. ^
- L! V. L' X' F1 Z: j
# ^6 W# d4 S2 o- b4 U* U, B
       uwSynchPrediv = 0x7F9 A) p1 y; b: x8 i
& y1 U' t$ V3 P9 S# A6 \4 d
, T! _, z: D! v4 e+ X
ck_spre(1Hz)=RTCCLK(LSE)/(uwAsynchPrediv + 1)*(uwSynchPrediv+1)
9 l8 I$ s. S0 T4 v* M' q" x# z4 ?2 R& D" o: U$ c, j4 g( c% F% s

8 d: B* M! e/ L* d# zRTC_InitStructure.RTC_AsynchPrediv=uwAsynchPrediv;
7 d9 K7 V" x% P
4 a3 o2 F* `, k% a$ K3 A

( q2 s& w) x+ }7 L' d0 oRTC_InitStructure.RTC_SynchPrediv=uwSynchPrediv;$ h7 n( @9 F/ Z. i- i; g6 X

) z+ g2 r* ?+ W0 z        //24/12小时制   ! B4 C) y5 D& M$ S! }
; G. d& [5 A0 M5 h; }( a
" E8 f7 u$ w2 [$ _
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
; L$ L8 v8 J; n2 r$ H
, J) N: S1 g$ v7 H. y* ]% d

: E" d1 F6 e4 w- F8 g' ^RTC_Init(&RTC_InitStructure);
* I: Q5 t: v, o* u# w$ w) _9 k7 w; j, I4 d$ n& K7 i! e3 q

- d* Q) A' A* `1 }+ o( p6、时钟在不掉电的情况下只需要初始化一次即可,程序复位防止多次初始化,在BAK区域写初始化标志,可解决;
  i( j- j" N' U4 K3 a1 ]3 a( @$ P
; w" u8 B4 v& O8 {! x9 _! t
2 o( u0 T! S$ V$ v9 h" @
    RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
, D" @/ g) u( W7 b/ A/ g: [/ x: [  \4 k  S+ P- N' }
    初始化前,读取RTC_BKP_DR0,查看是否为0x32F2,如果是,表示已经初始化成功。4 u- l! q) X# I7 c- h- d4 X  T8 ]. L

9 |: s0 X/ T9 M' ^$ g

% u7 G) H4 u4 X' b( Vif (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2)
$ |6 V. ]9 v5 p* q1 d0 Q
/ o) f" G" N/ k" B  n. j" q7、读取日期时间
  Y5 L4 {3 e" b  R" w+ p6 ~* ]" k6 c& x5 Q3 b% Q
7 b  Y/ [  E4 t4 S; e2 b  {
    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);4 z1 `# `/ v# S* C" T
6 h" C& o; W8 C  z# _( o' x

0 ?) D: r- x- B8、写入日期时间- |# U% |9 ?' c) c* ~7 f
* Y/ G( {2 S, L% d# e( U+ s1 z
$ d% b8 H6 C$ @2 [
    RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);   
  w5 V# B6 c4 Y' a; O  R
% G( `& S* M/ g1 R& o
8 k: v, c$ f; w% s$ y7 U  e2 H
; I1 `# }- A! s$ `2 p5 M9 d* Z- T

" Z, W* E( a/ @) l3 B( m* `% z3 w& D# m0 C* M7 @

6 W( O$ O& _5 w: O3 T0 Q2 {0 \下面为此篇文章的重点
* v* A7 d! `  V: {/ W
' T! Z$ G3 t% g- I# \, U6 x. h. B
5 [: Q+ G# r, d" o0 Q
系统里面保存事件或者打印信息,都带有时标,不可能每次都去操作MCU的总线去读取RTC寄存器获取;或者是外部RTC芯片8025,IIC接口;
: p6 y5 F* i/ X, F8 F8 [+ A8 G" @1 g( h( Z. I
) ]9 z2 O% C5 V, o# r9 P  r7 v5 _
直接操作硬件缺点如下:7 L; Q: Q& Y" L! |
$ S  m( B1 {! P3 k/ k

1 t4 V% B7 W) z- |( m) ]0 I. P% \4 Y8 K1、直接从硬件中获取事件,精度很难取到ms级别,芯片最小刻度为秒;; d0 u- e9 \! R/ u& @4 W: w
2、操作总线占用系统资源,降低MCU性能;% V8 Z7 p, X/ o* g9 s

; }% h  o% [% z' U
! O4 Y# @, s" e1 ~
为解决这个事情,需要系统中有个维护软时钟功能,接替RTC的走时;
7 N5 W2 }2 a% q+ Z6 O! n- Z
6 ~; Y' K7 F- p* u4 o- H' J: U! h: S
) s( z; Y+ l4 @+ K
具体做法为:% J. l8 F1 q; ^6 R

" H7 `0 _$ ~6 T  E  _$ n+ F$ @& _; r

( }* O) u/ r7 D1 {1、开启定时器,具体根据需求定义周期,可开启一个1ms定时器;
8 D* c4 `) N$ D. P$ X) g2、软时钟1ms累加计数,1S=1000ms;累加到1000,秒数加1;
% ]5 e, b  K" W! z3、防止走时误差大,一小时建议同步一次时钟,从硬件RTC中,把时间读取一次到软时钟同步;
) P+ x0 e% n7 d1 b" P) S" V
$ A0 v+ ~9 ]4 ?0 S  O( A  |
赞 1 收藏 2 评论0 发布时间:2020-12-4 14:27

举报

0个回答

所属标签

相似技术帖

官网相关资源

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