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

【经验分享】基于STM32使用HAL库驱动RTC时钟及闹钟功能

[复制链接]
STMCU小助手 发布时间:2022-4-10 17:01
(一)工程配置( c+ T3 G6 h" }" v) l
我使用STM32F103RB这一款MCU,首先使用STM32CUBEMX创建工程,配置主时钟和RTC时钟,我板子上是使用的外部的32.768K晶振供RTC:9 L  X' G; c9 B2 I3 n/ P! R0 q( a

" s' k) f; Y: Z1 N9 c" P+ ~ C3{M])]J4ZHAZ}[7HY3$V61.png
3 i3 l, \# z: g 97GQ`99{Q(TOSDHE5R}`J8G.png % ~/ L. U/ n- b6 M
9 O9 V* Q7 S1 l( F5 A- S; M
配置了两个LED灯:
5 c2 l! p; f# N' d

3 f1 P' Q' V/ u E1TKCWX3P$W{AZ0{TE)NX]P.png " c) u: ?$ k. h) h' _

' S2 _. Z; V4 E0 ?3 v3 g配置调试下载接口为SWD(此步骤如果不配置,你使用stlink的话下载一次程序之后就再次下载就会找不到MCU):
0 n1 z+ M- }7 E/ V
9 \9 V' m! _  {6 s. ~0 [' _ `6T2@4B$L10P(QAQTU4~Q1M.png " z: k7 Z5 w' ?! n: |; S9 ?4 @

7 A/ J+ Z& t9 S& V8 j. R* d7 L! c配置串口1:
7 Y; N9 m# ?7 s5 d- S# Q$ }' ?; R2 R8 z0 }& N' Q
O~75A%RI1CY(35W%_8_27QQ.png 9 ]# ?' X( {: [- ^

; K5 r  x2 r) \. A5 V' J配置RTC时钟,激活日历和时钟源,这里我设置时间为2020年12月25日0点0分0秒,设置闹钟提醒的时间为3s:0 K6 T# [& X+ v. Z
7 b0 d+ z- w6 A' l" G/ y
01O~~)LP[7AT~BC{8ZMQRCM.png 2 z' I4 y8 t$ V

9 L/ V1 d$ g% |( `+ i) b使能RTC闹钟提醒功能的中断:+ Y/ h0 M2 G/ X7 f- S. n
- V0 ?( |# e& ]! p
0@S}$_5{DKF`~OL1(71XUYY.png ; k; U) R! J, W3 V2 e

- @/ Z2 [( B7 A4 T7 F7 v其他工程设置:

8 f- E7 M6 Y/ e  A% g! M3 d- ?5 D6 C! Y7 }4 u; t
$KVEO9DZGAMPO8E3%RRVGGU.png
0 V" B1 d% ]$ l; s) x2 v3 F, h( X1 M1 a$ F# B% ]
然后生成工程就可以了。
" a& K0 ]: ?5 y( ^- h0 `0 F6 ]1 e9 Z: |+ `& P$ n- m- P
(二)代码编写

* t% z4 B6 ?# V! X重定向printf函数:# O2 x/ X. i1 O4 N2 F

; O7 b' Y: C( a  t4 U
  1. int fputc(int ch, FILE* fp)
    : \" O$ A# T$ ~2 p
  2. {
    ! ]5 u2 ]$ b6 k: ^" h- b
  3.     while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);: P! V: |, }9 L+ E
  4.     huart1.Instance->DR = ch & 0XFF;$ Z( X8 f- ~2 q9 r" ?
  5.     return ch;
    8 B8 F1 p- \7 P2 S& J
  6. }
复制代码
% r$ o4 k  ?0 {+ [
HAL库获取RTC时间的函数有两个:3 m* k8 F$ b8 N3 Q
HAL_RTC_GetTime:获取时间7 s; U/ M2 k+ f) K$ K
HAL_RTC_GetDate:获取日期
) h6 d0 V) o- X' |4 B; M5 D5 m4 w& P, ^+ G, g! l0 W
这两个函数的第三个参数是格式:RTC_FORMAT_BIN和RTC_FORMAT_BCD,BIN格式就是十六进制数值直接表示的时间数值,BCD格式就是用数值的十六进制面值表示时间数值,例如表示第24分钟的时候,BCD格式的分钟值就是0X24。. g: h8 {: C  i8 r2 w

! R* m5 ]* u; F+ N( i; L注意:
这两个函数调用是有先后顺序的,必须先调用HAL_RTC_GetTime然后在调用HAL_RTC_GetDate。
1 s4 G" e2 {- f& b3 `, I! }
0 b9 v* d9 f) c6 U; w2 r4 I3 `可以通过以下两个函数设置时间:1 O* y' R, h  ]0 O9 y; O, }: D  I
HAL_RTC_SetTime
8 a, j8 E$ W( q6 U# p$ q5 S5 r' `HAL_RTC_SetDate8 i, \5 m4 |& c+ o8 f; G

, e/ G/ P  y  A2 ~0 ^* q9 c这里我简单的把时间设置的函数做了个封装:/ P: a+ ]; k2 u( y) X" [* G! c

$ E4 m! R- I( z- n
  1. #pragma pack(1): ?4 z: O6 y  e0 x9 O
  2. typedef struct
    - w( q' V/ _% M) b' }( n2 k( `
  3. {
    5 H2 [/ Z  T  F( u$ q
  4.     uint8_t Hours;- `% f; \7 }- U, t3 g
  5.     uint8_t Minutes;
    4 H* Y- m) E1 @, C. ~% u6 ^/ z) a
  6.     uint8_t Seconds;
    8 H3 s9 G1 a6 G, l; n& g4 r
  7.     uint8_t WeekDay;
    6 S9 d, \5 w3 d/ A/ p
  8.     uint8_t Month;9 Q3 f9 I, V& z/ G8 T
  9.     uint8_t Day;! n" {/ F2 P5 L/ Z+ y; J
  10.     uint8_t Year;7 h7 P0 U5 {; i4 E
  11. } rtc_time_t;
    , N# H$ v- A1 E) c2 w3 \% n; @
  12. #pragma pack()2 A4 `2 M; {# J" U
  13. - ?! R7 g0 B: M# Y# O
  14. 1 N! m6 v, d5 s4 L! n
  15. void RTC_GetTime(rtc_time_t* time)2 C$ }+ b+ }& N. e3 M
  16. {- c4 d  e5 L) U: P! Y* h' W
  17.     HAL_RTC_GetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    ) ?& X) J  c! |1 a
  18.     HAL_RTC_GetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);
    ( \! ^& t7 f' y: y6 z0 j) X
  19. }
    # n- x7 j2 n6 _1 t4 l3 J8 c
  20. * O( B) t% [9 x% c
  21. void RTC_SetTime(rtc_time_t* time)
      `7 n, h  i1 n" o8 |1 r1 [* ^* x
  22. {+ G9 f: |( |6 W' @0 z9 k5 l# m
  23.     HAL_RTC_SetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    9 v6 h& ]" W* M7 l/ _# b" {
  24.     HAL_RTC_SetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);+ W/ q/ l. \. J, q! s6 R, b' y
  25. }
复制代码
8 v! [# Q5 N. y
覆写闹钟时间回调函数:
" O. L3 ?( N# j; F; l% Z
! F3 L7 h3 l. T, ]/ s闹钟事件的中断设置,要看MCU支持的是秒中断还是时间中断,比如10X系列,要通过当前时间去设置下一次闹钟,而40X系列的可以直接设置时间。
7 W$ ^% L2 J. O8 y; T5 B# ?  n' |6 }4 R! i( s: w
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc): q0 ~0 E$ A; b. h+ i  m
  2. {
    , Y' L- _% }- }
  3.     RTC_AlarmTypeDef sAlarm = {0};
    & j4 a5 h! _/ V: b5 ~5 z: T
  4.     rtc_time_t tim = {0};; d5 G; N5 l0 I

  5. , J. A  \3 O+ n4 A% l) C& H# Q
  6.         // 获取当前时间
    / n6 I2 p; L9 v% r4 I1 z
  7.     RTC_GetTime(&tim);- n! {# S, D" w$ s

  8. 9 T' y$ V: k5 s. u4 F% J
  9.     sAlarm.AlarmTime.Hours = tim.Hours;
    " j( G! O6 y: n. Q
  10.     sAlarm.AlarmTime.Minutes = tim.Minutes;" `# D. a& J' A! _9 G" @
  11.     sAlarm.AlarmTime.Seconds = tim.Seconds + 3;  /* 设置下次闹钟提醒时间是当前时间的3s之后 */
    + I4 G% q0 I" s' i  B9 x
  12.     sAlarm.Alarm = RTC_ALARM_A;+ D+ q' A7 ~% w; @8 l. I
  13.         
    1 k1 u% m1 G# R0 z& I8 i2 h
  14.         // 再次启动闹钟中断事件
    6 b- V( B" C( |$ p
  15.     if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
    ; Q1 M' E% y( d/ n5 K- G
  16.     {
    - [7 ~8 g/ o' a0 H
  17.         Error_Handler();5 D4 S8 N0 e, w" L2 ~
  18.     }
    - M; \7 U! @4 ^5 l& H
  19.         / P9 I. V0 B6 e- D, ]- T$ q
  20.     printf("HAL_RTC_AlarmAEventCallback\r\n");
    $ m/ Z+ j9 ^: U/ G* p( I0 w/ ?
  21. }
复制代码
" _5 K. J. V& P5 i! w
main函数:6 d% k, r- @3 f
3 N: R/ H/ V' w$ J& I& u
  1. int main(void)1 a% U$ q& {0 O1 k
  2. {
    ; c- k0 j! `0 i, V9 [
  3.     rtc_time_t tim = {0};
    # F. l8 f* z7 s% i$ Y+ N; X' v
  4.         ! L$ b, ?, o% [, ?. r  {( ^4 M
  5.     HAL_Init();
    ( k" I# I# |" h* y. ]: S9 [
  6.     SystemClock_Config();5 [  A+ m5 t0 H
  7.     MX_GPIO_Init();
    7 k% G+ ?0 G6 B  c
  8.     MX_USART1_UART_Init();' A0 K% N( _, A7 p9 `
  9.     MX_RTC_Init();
    ; x3 V2 t  @' G% e/ q+ c8 H

  10. : B7 w0 c& f$ L; p* R5 n1 u7 m6 [
  11.     while (1)
    # D& I2 v4 n" m# X* V
  12.     {8 o. V1 a& e0 R$ R2 I
  13.         HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);( n2 S& Y' j, \% }& ]3 \
  14.         RTC_GetTime(&tim);
    5 A6 N( q% @4 h' }6 ]5 O; X+ i
  15.         printf("%02d/%02d/%02d %02d:%02d:%02d %d\r\n", tim.Year, tim.Month, tim.Day, tim.Hours, tim.Minutes, tim.Seconds, tim.WeekDay);" V5 v) J( n% x" a5 ]! L- e/ T
  16.                 HAL_Delay(1000);) s  q5 w1 \" F  c! T% W
  17.     }, `$ \, _. ~2 ~
  18. }
复制代码
  ^% ?2 J1 v; V
(三)运行效果5 t5 \: z. b  J$ N, U! r

- c4 [' H+ g% r, i/ G3 `. \$ _/ U6 j 20201225092230509.png   ?" ^9 U" e" _" ]

5 W: h1 G  J. q; S! `5 L0 O! E& \( Z) R# ]* e

5 n2 u1 l; E  f" x
收藏 评论0 发布时间:2022-4-10 17:01

举报

0个回答

所属标签

相似分享

官网相关资源

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