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

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

[复制链接]
STMCU小助手 发布时间:2021-3-9 13:11
STM32学习笔记 | RTC日历基础应用问题分析
) k" y! ]; m3 h6 C# u; h
RTC,Real_Time Clock,即实时时钟,在许多电子系统中都能看到实时时钟的存在。
# O# }) v9 @6 @2 U( E/ O
每块STM32内部都集成了一个RTC模块,是一个独立的定时器/计数器,具有计数、时钟和闹钟等功能。
; p6 O# T. g& n4 U) P( ^# \
STM32 RTC 基础内容

# F3 @/ ^# Q0 M0 @
STM32内部集成的RTC相当于一个TIM,具有计数的功能,但和TIM有一些区别,比如供电来自备份区域,可作为低功耗模式自动唤醒单元等。
STM32的RTC除F1系列不具有BCD寄存器(日历功能)之外,其他系列的RTC大同小异,本文以F4系列RTC为例进行讲述。

* r* V- O% ~* A; `
1. RTC时钟源
  Z; o3 |: ?4 M& G
RTC不具备自己输出时钟信号的功能,和TIM一样由内部,或外部晶振提供时钟源。

7 h4 N# h1 X. G8 C: m" S
通常是由低速外部晶振(LSE)32.768kHz,或者低速内部晶振(LSI)提供。内部晶振误差大,如果要求高精度需使用外部晶振。

2 s2 K) g6 {+ G2 C
当然,还可以使用高速外部晶振(HSE)的分频信号作为时钟源,但该时钟源有最高频率限制。
7 {! r" S+ h- i0 c" E9 d$ l
2.1.png

2 i. V5 {4 i! I6 N% ]4 q8 G( o; ^
2. RTC日历

5 V( V5 e0 x4 N) {7 n: |- V
RTC的日历功能算是一个比较重要的功能,但是在早期的F1系列中不具备该功能,需要结合软件计算才能实现日期和时间的功能。
除F1系列的RTC自生具备日历功能,即具有日期、时间、亚秒等于日历相关的寄存器,只需要直接读取寄存器即可获取日历信息。
同时,系统可以自动将月份的天数补偿为 28、 29(闰年)、 30 和 31 天。并且还可以进行夏令时补偿。
! i2 O  B! V% q9 T4 R: c* r1 T
3. RTC闹钟
# ~8 h7 S# h/ ]5 {- j9 H
RTC闹钟功能也是一个比较实用的功能,大部分RTC都具有两个可编程的闹钟:闹钟A和闹钟B。
RTC闹钟可产生中断信号,也可以产生闹钟输出信号。
# f' o8 S+ v8 p2 ]8 @7 x
4. RTC自动唤醒

# P  M; g; e0 o8 K1 u/ K  v* C& y
有的产品需要周期性唤醒,比如间隔5秒唤醒一次休眠的芯片。
RTC自动唤醒由 16 位可编程自动重载递减计数器生成,通过 WUTE 位可扩展至17位。如果频率为1Hz,则自动唤醒时间可以 1s 到 36h 左右。
以上是重点知识点,更多细节请查阅芯片对应的参考手册。
: R2 E" m( A4 H0 L
STM32 RTC 参数配置
) f% b' e" v' `- ^3 @5 {1 B
STM32 的RTC使用比较方便,不像TIM各种复杂的关系,可以通过STM32CubeMX很简单就能使用RTC的各项功能。
下面以F4、Cube配置日历为例。
8 }$ W! W: ?8 U0 A" X1 J
1. 配置时钟源
! o( W8 O! z, F& i
2.2.png

9 r" y; _+ _$ x" k2 y- V
2. 配置分频值

& {" w- S! Q- ^3 N4 k+ n. K6 E: [% u/ E
通过32.768kHz信号得到1Hz分辨率,可参考例程默认分频配置:
32768/128/256 = 1.
备注:从0开始分频,所以配置的分频值需要减一:127 = 128 - 1, 255 = 256 - 1.
# s) ^. U! T/ C  o' z
3. 初始化时间和日期
+ T- T) i# H+ n1 f8 \2 M; a# y2 `2 K
通过Cube工具初始化时间、日期以及格式:
2.3.png
) v, T4 _) Z9 _
以上就是通过Cbue工具配置的参数,生成的代码:
  1. <font face="微软雅黑">static void MX_RTC_Init(void)
    . E8 z) b' Q* b3 p* w* [* g
  2. {) Z# Q9 [6 T1 W8 E1 Z" u
  3.   /* USER CODE BEGIN RTC_Init 0 */3 a; V$ {, I5 x( E. m" T
  4.   /* USER CODE END RTC_Init 0 */' A( c( M) W: \' }, |
  5. ( z! v! S1 c) [+ u. q5 P, G
  6.   RTC_TimeTypeDef sTime = {0};, W" D/ o. y6 }8 \
  7.   RTC_DateTypeDef sDate = {0};4 t9 g6 V1 }+ q: ?4 P, T
  8. 3 C; I& c- q: a% L' x2 S9 n. ~& Q
  9.   /* USER CODE BEGIN RTC_Init 1 */
    ! i* p0 |. h7 c
  10.   /* USER CODE END RTC_Init 1 */6 E' {, }' {& S2 l- g
  11. 8 J; X1 d# g+ W( o# u
  12.   /** Initialize RTC Only
    $ y" \# W# t( D7 b
  13.   */+ a) X5 O: z7 ^; C9 k0 u
  14.   hrtc.Instance = RTC;" ^. g3 u9 A# Y8 R1 L6 R$ w; U& @
  15.   hrtc.Init.HourFormat = RTC_HOURFORMAT_24;8 R4 ?, }% F6 g2 d- w
  16.   hrtc.Init.AsynchPrediv = 127;6 A+ l$ ^& w' V0 u
  17.   hrtc.Init.SynchPrediv = 255;
    ' [1 Y* H! W6 Q( @" h
  18.   hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;6 @2 r. B) v+ n( I3 X; F( D
  19.   hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;& j% U; W6 Q" \/ L! n
  20.   hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
    2 P+ E$ F0 K; E- K+ o
  21.   if (HAL_RTC_Init(&hrtc) != HAL_OK)
    6 I2 l: S7 j# L  e
  22.   {
    , v- i3 D1 O/ a( b; H$ S: G' H
  23.     Error_Handler();4 A2 k' K6 _; H# c- H4 ?
  24.   }
    3 V) L) C, |& R- N1 q4 n

  25. 4 m# O7 z6 G; Q, H
  26.   /* USER CODE BEGIN Check_RTC_BKUP */" l0 W- m, P; ]1 V; V' t
  27.   /* USER CODE END Check_RTC_BKUP */; Y% V* Q, T. E( a" U2 z, G
  28. 8 C3 _9 M4 Z9 B! O; t5 g
  29.   /** Initialize RTC and set the Time and Date 9 Q0 w5 U. Y- \: |
  30.   */2 N) J: h$ O+ \- f4 H) J  b
  31.   sTime.Hours = 0x0;
      m$ e8 J' x4 T) o/ A7 A1 M
  32.   sTime.Minutes = 0x0;
      G0 E7 t; T& n8 ]
  33.   sTime.Seconds = 0x0;
    : u# u4 m- r2 b1 h% ?
  34.   sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
      l0 a) R, N+ e+ K$ H6 @
  35.   sTime.StoreOperation = RTC_STOREOPERATION_RESET;' \+ ]3 w) O4 f% W! r; j5 s3 D
  36.   if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)+ P$ F' a! t+ s+ x( ]
  37.   {
    # S% o8 J, L/ `$ Q0 A- @
  38.     Error_Handler();( N3 G. a+ O0 d0 a0 H( h
  39.   }! v" }/ ?6 h* e6 L2 x
  40.   sDate.WeekDay = RTC_WEEKDAY_MONDAY;7 k4 c! i& M1 p# a0 i
  41.   sDate.Month = RTC_MONTH_JANUARY;
    $ U; B7 |( Z! B" G0 l4 i* k% X
  42.   sDate.Date = 0x1;
    + Y; E' N7 F; L+ X  r; q
  43.   sDate.Year = 0x0;& ^" A; `) M/ }1 b' ]8 P5 F" P
  44.   z. O6 `$ B+ s+ [
  45.   if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)' B5 l$ e, G3 H+ p
  46.   {$ ]# H& b( [* B. e. x! M. ?. ?
  47.     Error_Handler();
    : K1 V: ^% X- m. q
  48.   }* b0 M( S( t3 t' Z% j9 s4 z' c- q
  49.   /** Enable the WakeUp , `2 d! ?$ O+ K* M8 B
  50.   */2 ^. y4 E( ~2 S. }7 A
  51.   if (HAL_RTCEx_SetWakeUpTimer(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)5 w1 s5 u2 ]0 {1 d
  52.   {( f; B& v- a  M! d
  53.     Error_Handler();
      V% q0 I9 u. R3 r) r' i
  54.   }
    , V3 p( Q3 t* c( c% _
  55.   /* USER CODE BEGIN RTC_Init 2 */9 C( j6 v2 [" G, h
  56.   /* USER CODE END RTC_Init 2 */$ F3 n4 q0 D. K
  57. }</font>
复制代码

. L1 g# ]8 G: `; @& I# h# ]8 m. V
RTC通过Cube工具配置比较省心,如果使用标准外设库进行配置,就需要注意很多细节,简单参考官方提供例程。

% O: F6 P# W8 ]! P; q$ E
STM32 RTC 常见问题

' c8 B, p' d) ^/ R
STM32内部RTC模块应用场景相对简单,不像TIM有复杂的配置以及关联性。但使用RTC仍需要注意一些细节问题。
  [" o* ^) k2 p# i8 P$ ^4 ?1 x
问题一:RTC时间不准
有不少工程师都遇到过RTC计数一天,相差几秒甚至几十秒的情况。导致时间不准最根本的原因是时钟源,还有时钟分频值。
低速内部晶振(LSI)的误差相对较大,特别是温差变化较大的环境。
还有关于时钟分频值,上面已经提到了分频128,实际配置参数应该为127.
解决办法:使用更高精度低速外部晶振、校正、软件配置正确分频值。
0 q& g3 s1 @$ t/ c: |
问题二:RTC时钟配置失败
RTC的供电来源备份区域电源,操作RTC之前,需要使能后备区域操作。如果没有这一步操作,你会发现操作低速时钟、RTC可能会失败。
当然,出现这种情况,一般是使用标准外设库配置导致的失败。
解决办法:使用Cube工具,或参考官方例程初始化代码。

& d. C# R/ r: Y
问题三:RTC日历不更新的问题
在我们的RTC应用中,经常有人反映在做日历数据读取操作时发现日历不更新的情形。其实,STM32  RTC的日历寄存器由两个组成,为了保证读取时间点的一致性,先读时分秒然后读日期做为一个完整的日历读取操作。在读取TIME【时分秒】后,硬件会将当前日历数据锁住,直到DATE【年月日】寄存器被读取后释放。否则会遇到读取日历时发生数据不更新的情况。
解决办法:对于RTC日历的读取要注意读取动作的完整性,读了TIME还要读取DATE才算一个完整操作,以保持读取时间的一致性。

3 A" [+ Z9 N, Z; z
复盘一下
▼RTC 基础内容:时钟源、日历、闹钟、自动唤醒;
▼RTC 参数配置:时钟源、分频值、初始化;
▼RTC 常见问题:RTC时间不准、RTC时钟配置失败、重启会复位RTC时钟;

/ A$ Z: ]# [; `4 a+ M
文章出处: STM32

% O# M; d; c* V) E& m
& E% T7 @) @0 D6 z& w, B4 O8 w9 P
赞 收藏 评论0 发布时间:2021-3-9 13:11

举报

0个回答

所属标签

相似技术帖

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