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

STM32学习笔记 | RTC日历基础应用问题分析

[复制链接]
STMCU小助手 发布时间:2021-3-9 13:11
STM32学习笔记 | RTC日历基础应用问题分析
& \/ I2 y4 @9 w4 x% Q* I
RTC,Real_Time Clock,即实时时钟,在许多电子系统中都能看到实时时钟的存在。
* k: ^: S3 ^0 ?! W+ d
每块STM32内部都集成了一个RTC模块,是一个独立的定时器/计数器,具有计数、时钟和闹钟等功能。
& ^8 x1 S8 U( w4 u8 _
STM32 RTC 基础内容
* s3 O: K5 O/ d- a  m3 B% j; @* E
STM32内部集成的RTC相当于一个TIM,具有计数的功能,但和TIM有一些区别,比如供电来自备份区域,可作为低功耗模式自动唤醒单元等。
STM32的RTC除F1系列不具有BCD寄存器(日历功能)之外,其他系列的RTC大同小异,本文以F4系列RTC为例进行讲述。

; R- G' f6 Y" ^" l$ a% h
1. RTC时钟源
- H( c2 X! s' o9 \9 C
RTC不具备自己输出时钟信号的功能,和TIM一样由内部,或外部晶振提供时钟源。

+ i" u: g3 D, C; U$ A4 p9 f2 F( B9 ^
通常是由低速外部晶振(LSE)32.768kHz,或者低速内部晶振(LSI)提供。内部晶振误差大,如果要求高精度需使用外部晶振。
, V; K/ M6 f* h3 r* I6 D( Z8 f
当然,还可以使用高速外部晶振(HSE)的分频信号作为时钟源,但该时钟源有最高频率限制。

# f, Y$ G4 ^) B! t9 u( t
2.1.png

9 h3 h& ?, I8 Y+ H) K, I
2. RTC日历

0 s$ i. d' \5 T# p: _3 X! T  G, T
RTC的日历功能算是一个比较重要的功能,但是在早期的F1系列中不具备该功能,需要结合软件计算才能实现日期和时间的功能。
除F1系列的RTC自生具备日历功能,即具有日期、时间、亚秒等于日历相关的寄存器,只需要直接读取寄存器即可获取日历信息。
同时,系统可以自动将月份的天数补偿为 28、 29(闰年)、 30 和 31 天。并且还可以进行夏令时补偿。
# @9 T/ L3 d9 G0 V$ S3 C
3. RTC闹钟

* E" d" h8 ~0 a8 U' b. ?! Y
RTC闹钟功能也是一个比较实用的功能,大部分RTC都具有两个可编程的闹钟:闹钟A和闹钟B。
RTC闹钟可产生中断信号,也可以产生闹钟输出信号。

$ f: z# Y: i4 T' A" ?2 E# {
4. RTC自动唤醒

9 v* }# q/ C9 a  T
有的产品需要周期性唤醒,比如间隔5秒唤醒一次休眠的芯片。
RTC自动唤醒由 16 位可编程自动重载递减计数器生成,通过 WUTE 位可扩展至17位。如果频率为1Hz,则自动唤醒时间可以 1s 到 36h 左右。
以上是重点知识点,更多细节请查阅芯片对应的参考手册。

! v* B' g" U$ w1 h  D% U% d- L. d: Z
STM32 RTC 参数配置

& D5 O1 I  h7 d' M0 @
STM32 的RTC使用比较方便,不像TIM各种复杂的关系,可以通过STM32CubeMX很简单就能使用RTC的各项功能。
下面以F4、Cube配置日历为例。

, n3 n/ v9 K/ \7 i% f" N) s
1. 配置时钟源
) q( P: R+ c& X/ [' i! |
2.2.png
, @9 n; B9 j% u5 M" f0 `+ C7 V# i
2. 配置分频值

) ~2 t) {8 ^  }; u$ N
通过32.768kHz信号得到1Hz分辨率,可参考例程默认分频配置:
32768/128/256 = 1.
备注:从0开始分频,所以配置的分频值需要减一:127 = 128 - 1, 255 = 256 - 1.

3 k8 Z: B3 F9 ]& d
3. 初始化时间和日期
- d  P0 |3 G3 F
通过Cube工具初始化时间、日期以及格式:
2.3.png
8 E1 b) h' x, u. K8 N1 W- b
以上就是通过Cbue工具配置的参数,生成的代码:
  1. <font face="微软雅黑">static void MX_RTC_Init(void)
    . M3 C7 S& N7 r* U- f8 @
  2. {1 y+ h: w. N0 g4 B
  3.   /* USER CODE BEGIN RTC_Init 0 */
      e3 j1 K2 r, }3 R9 H, \. D, u
  4.   /* USER CODE END RTC_Init 0 */8 T' j7 E, r% U+ ]9 e
  5. # O1 o2 j8 V& `5 I
  6.   RTC_TimeTypeDef sTime = {0};- J  y! f) Z' q/ u6 w/ q4 c! Q
  7.   RTC_DateTypeDef sDate = {0};
    $ n& v4 m8 _! L/ u3 B5 w

  8. ( [* }; V! a* ]
  9.   /* USER CODE BEGIN RTC_Init 1 */+ i6 v9 e4 s  p0 K- k# K0 n. z
  10.   /* USER CODE END RTC_Init 1 */
    - z9 B. f- R5 |7 r9 ]+ v2 W& E

  11. 2 f% _9 o" m) T- z- q0 C! W6 \6 ]
  12.   /** Initialize RTC Only 1 E6 H: Z4 P7 ~( s/ w" }; A. R# N  U
  13.   */
      W0 |! A& F" d0 t+ o8 x* `
  14.   hrtc.Instance = RTC;8 c2 c6 d" G) j) [3 o
  15.   hrtc.Init.HourFormat = RTC_HOURFORMAT_24;# O' Y; H( G0 {5 @% l; |1 x
  16.   hrtc.Init.AsynchPrediv = 127;
    * R& M. h! O# d& u2 K6 d
  17.   hrtc.Init.SynchPrediv = 255;
    9 K2 o5 v8 g  l5 n" w2 @
  18.   hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;4 g9 p7 O/ `' }, M5 k$ S
  19.   hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
    ) k$ _5 N+ V" S& ?& P$ K' P
  20.   hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
    9 j# O6 j# k7 c) _0 O
  21.   if (HAL_RTC_Init(&hrtc) != HAL_OK)
    " Y0 s! C& }4 W. U& @
  22.   {( d4 Z8 z1 b  U' Q7 j6 `) E7 v
  23.     Error_Handler();
    , C1 E' {1 v1 \2 s8 Z# a* c9 }4 g
  24.   }+ F2 h# j1 W$ h. r2 z" K- p% r

  25. 1 w% v9 x' _6 X  k$ e% M+ h
  26.   /* USER CODE BEGIN Check_RTC_BKUP */
    2 e- B* a5 ~: _- M+ E( ]* `4 M
  27.   /* USER CODE END Check_RTC_BKUP */1 n1 w, x4 Q1 x; i) m% \+ b- D
  28. # k' X. S4 O. E9 {( f$ w) y
  29.   /** Initialize RTC and set the Time and Date
    " A/ K$ @5 W: @3 |7 `
  30.   */  i/ D6 g" Q6 q: l1 T& D; C; I2 F
  31.   sTime.Hours = 0x0;
    / @; f, r$ H) D4 I( j9 i2 G
  32.   sTime.Minutes = 0x0;2 I( a4 y5 s. G% r, @& A
  33.   sTime.Seconds = 0x0;
    ' |8 \2 Z' \5 f0 J
  34.   sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    : o, P8 r$ j7 I
  35.   sTime.StoreOperation = RTC_STOREOPERATION_RESET;
    6 Y4 _, Z, z, Y
  36.   if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
    - V: t& W5 Y: x, {+ r
  37.   {% Q$ U2 \: B; W, @2 c) ^
  38.     Error_Handler();5 o, T1 U9 o- x: h
  39.   }4 |9 o5 O$ h4 s% V) W
  40.   sDate.WeekDay = RTC_WEEKDAY_MONDAY;# n# {  P( r1 o8 Q+ ]
  41.   sDate.Month = RTC_MONTH_JANUARY;0 l; i& M2 g0 W" u. ?$ n
  42.   sDate.Date = 0x1;- `2 ?) f1 V6 p7 T
  43.   sDate.Year = 0x0;
    - a7 I% p4 K$ n& r" F

  44. # ?' k1 G9 B) S
  45.   if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK). e" f3 \8 }; J' c% k0 G
  46.   {
    + J1 u. c8 C/ d3 i# H( k" b/ ^
  47.     Error_Handler();0 @6 G6 q! L4 b) w  _& A  `
  48.   }  |# r* Q) r+ ~6 E' e, C3 s
  49.   /** Enable the WakeUp / U7 J( Z6 n+ _$ L8 J) w% B7 O
  50.   */8 K9 Y. J5 L% n) t- k
  51.   if (HAL_RTCEx_SetWakeUpTimer(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
    ) n' r7 ~  {; o; j3 H6 W: l1 Y
  52.   {
    6 f! `' m( G' Y
  53.     Error_Handler();8 [- n( U) v. t$ a) {' {: _
  54.   }
    1 b7 F9 r; y, |/ t
  55.   /* USER CODE BEGIN RTC_Init 2 */  ^7 x, L4 _* H& ~3 S1 k  A! U
  56.   /* USER CODE END RTC_Init 2 */: K* l! ^9 p6 Y2 t* c
  57. }</font>
复制代码

$ O, ], a" R. T( d2 q
RTC通过Cube工具配置比较省心,如果使用标准外设库进行配置,就需要注意很多细节,简单参考官方提供例程。

" O& s8 S) ]/ T' ~5 h, y* D
STM32 RTC 常见问题
# a4 R8 K& X; x2 [
STM32内部RTC模块应用场景相对简单,不像TIM有复杂的配置以及关联性。但使用RTC仍需要注意一些细节问题。

5 c- R( S# j4 P5 U! |2 d! d
问题一:RTC时间不准
有不少工程师都遇到过RTC计数一天,相差几秒甚至几十秒的情况。导致时间不准最根本的原因是时钟源,还有时钟分频值。
低速内部晶振(LSI)的误差相对较大,特别是温差变化较大的环境。
还有关于时钟分频值,上面已经提到了分频128,实际配置参数应该为127.
解决办法:使用更高精度低速外部晶振、校正、软件配置正确分频值。
* z+ b' G4 r- H4 B. x8 }6 D3 q1 k( T
问题二:RTC时钟配置失败
RTC的供电来源备份区域电源,操作RTC之前,需要使能后备区域操作。如果没有这一步操作,你会发现操作低速时钟、RTC可能会失败。
当然,出现这种情况,一般是使用标准外设库配置导致的失败。
解决办法:使用Cube工具,或参考官方例程初始化代码。
0 A* W) y! z. g8 R, Z. b; t) |( d
问题三:RTC日历不更新的问题
在我们的RTC应用中,经常有人反映在做日历数据读取操作时发现日历不更新的情形。其实,STM32  RTC的日历寄存器由两个组成,为了保证读取时间点的一致性,先读时分秒然后读日期做为一个完整的日历读取操作。在读取TIME【时分秒】后,硬件会将当前日历数据锁住,直到DATE【年月日】寄存器被读取后释放。否则会遇到读取日历时发生数据不更新的情况。
解决办法:对于RTC日历的读取要注意读取动作的完整性,读了TIME还要读取DATE才算一个完整操作,以保持读取时间的一致性。

% ?* M9 K. F1 R9 S/ `
复盘一下
▼RTC 基础内容:时钟源、日历、闹钟、自动唤醒;
▼RTC 参数配置:时钟源、分频值、初始化;
▼RTC 常见问题:RTC时间不准、RTC时钟配置失败、重启会复位RTC时钟;

" l+ X0 G! y' H" o" {& ?/ @
文章出处: STM32

0 S1 d6 ]" z- m& C8 u: A; z

0 ]5 U) k$ p4 m
收藏 评论0 发布时间:2021-3-9 13:11

举报

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