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

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

[复制链接]
STMCU小助手 发布时间:2022-4-10 17:01
(一)工程配置
, J; N1 r0 r( M/ R! H; h! g; K我使用STM32F103RB这一款MCU,首先使用STM32CUBEMX创建工程,配置主时钟和RTC时钟,我板子上是使用的外部的32.768K晶振供RTC:
0 e3 }  V% C1 Q' r& P% i, u, h
5 o1 v; H" F/ Q C3{M])]J4ZHAZ}[7HY3$V61.png
0 [. h: }, F, H# N& [ 97GQ`99{Q(TOSDHE5R}`J8G.png 5 m+ v  p0 I/ f% S- D% E

$ U* m. l! O  B6 n3 F) g配置了两个LED灯:

% a3 |+ U! Z( m$ Q+ o/ g; C( ^
% C! a, A/ @' B' u, ^. m- N E1TKCWX3P$W{AZ0{TE)NX]P.png 0 S) Z1 X; z: w

. |! f4 p7 {5 d/ o: {配置调试下载接口为SWD(此步骤如果不配置,你使用stlink的话下载一次程序之后就再次下载就会找不到MCU):
, [7 P  O6 m/ R' O  s$ L2 v6 N) R  V
  }" ]) z6 M5 K. v9 p5 E1 s `6T2@4B$L10P(QAQTU4~Q1M.png
( R3 Q; C' L' b( l( P& ~
' @1 s; K0 M. |配置串口1:3 f2 ~2 W5 |$ c- N% J- ~* B: R+ q
0 H: e& A0 R3 h  ]& @& t* o0 V
O~75A%RI1CY(35W%_8_27QQ.png
7 C8 G1 f9 q. M+ X! R
' m" J/ z9 p# r) e配置RTC时钟,激活日历和时钟源,这里我设置时间为2020年12月25日0点0分0秒,设置闹钟提醒的时间为3s:' L. W$ `; h9 ?% R* R

! ?5 S' i% d4 c- Q6 Q
01O~~)LP[7AT~BC{8ZMQRCM.png
+ R- T1 q  \% u7 l, X& C& P2 k8 g2 W1 u7 D5 y" \3 J
使能RTC闹钟提醒功能的中断:
6 H& S$ o  t1 f+ N' I: g
( @$ ~, M- V- ~8 e; _
0@S}$_5{DKF`~OL1(71XUYY.png 4 U5 w% Z4 F) Q( x

2 U& L8 o$ q' X1 [) \5 D2 T其他工程设置:
0 Y! X8 c2 c: W

, x- J" L: `2 U$ z. @& t/ Z $KVEO9DZGAMPO8E3%RRVGGU.png : w* C* G2 L( d5 [! m) v6 d4 Q
3 K0 k2 m; b. q, z
然后生成工程就可以了。
4 W' A- _' P& j7 E
" ^/ t, `9 E6 Z3 d" b. B$ E" p8 L(二)代码编写

% @) r' d9 x$ z4 z5 z! R  m重定向printf函数:
# r% j/ ^" e. i$ f+ @; z8 y1 O" r7 P) w9 @& D1 Q0 q- P8 s9 \
  1. int fputc(int ch, FILE* fp)
    ; t8 D; `/ u' m- J; h0 V) x- D( S$ a
  2. {
    # K+ m1 O) V9 w5 G: |
  3.     while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);. t2 L( o% V! z
  4.     huart1.Instance->DR = ch & 0XFF;
    & E. h: C" f/ R3 l- z3 w+ M! }
  5.     return ch;& u3 @8 E, C2 s5 i, x6 ?
  6. }
复制代码

  Y- i/ [6 ?- ~( R" b1 U, R/ I: @! ~HAL库获取RTC时间的函数有两个:% n: d' W+ W8 {3 C
HAL_RTC_GetTime:获取时间
3 u  S  r- W1 Y" vHAL_RTC_GetDate:获取日期# z4 e0 G0 g* }/ b/ `! y$ s, I, t

1 r  V- a; y8 e/ o这两个函数的第三个参数是格式:RTC_FORMAT_BIN和RTC_FORMAT_BCD,BIN格式就是十六进制数值直接表示的时间数值,BCD格式就是用数值的十六进制面值表示时间数值,例如表示第24分钟的时候,BCD格式的分钟值就是0X24。3 _& r' Q  ~/ h- M  C7 p
/ p- w9 v. L2 r9 I* U
注意:
这两个函数调用是有先后顺序的,必须先调用HAL_RTC_GetTime然后在调用HAL_RTC_GetDate。- L: m, w& u) C4 G1 n/ X
2 L* ^0 Q7 A! {% i2 ?
可以通过以下两个函数设置时间:
% s( k6 z' I0 S! Q& R" @HAL_RTC_SetTime" }5 a+ V3 l$ y% h8 w: J' e
HAL_RTC_SetDate
+ g3 P) r( t7 d$ S+ ]$ t% G+ ^
+ i9 k6 d! R, q1 f- [1 n! F这里我简单的把时间设置的函数做了个封装:! q8 C% ~0 |, B5 g0 }7 b
' v; w7 g+ u3 {' Q9 d* N$ h
  1. #pragma pack(1)+ I8 c2 a5 v- Q# q: @1 q
  2. typedef struct6 N8 t4 M- q- K2 \  X  f
  3. {" h4 o: ]9 V' g/ q
  4.     uint8_t Hours;; q% I- ?" `4 a" t7 k" `6 y
  5.     uint8_t Minutes;5 m& `& J! T8 {7 |+ d/ I
  6.     uint8_t Seconds;/ T, Y% ~% I5 w) d
  7.     uint8_t WeekDay;- G% Q" R' J1 i) w) A
  8.     uint8_t Month;
    / h4 x5 r7 Z( u6 F0 z- \/ U
  9.     uint8_t Day;
    # I- |% z) L3 V2 N
  10.     uint8_t Year;3 d1 }1 |7 j. b' q/ R( y1 _% I4 T3 d
  11. } rtc_time_t;
    0 @( Q7 d& A' s; L1 P$ E7 X7 W
  12. #pragma pack()
    : |; e- o. [1 M
  13. 8 e0 u+ _2 C) L: d
  14. 3 z2 q; w5 F. A4 x# C9 k! w
  15. void RTC_GetTime(rtc_time_t* time)
    # U3 T3 z  F) e
  16. {0 l- _8 A+ ~. ~4 \
  17.     HAL_RTC_GetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    . A* \3 I3 ~+ \- U9 t5 S
  18.     HAL_RTC_GetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);8 P  m, Z' w, I0 {2 y
  19. }: M' E! O. [) t- ?
  20. . C# g7 v4 h# r3 R/ P
  21. void RTC_SetTime(rtc_time_t* time)
    ( _8 ?+ Z+ i) `$ G$ L- A: Q, A
  22. {6 z# L6 @( G: v1 Y
  23.     HAL_RTC_SetTime(&hrtc, (RTC_TimeTypeDef *)&time->Hours,   RTC_FORMAT_BIN);
    3 h$ b% s  I' V; z' D( Y
  24.     HAL_RTC_SetDate(&hrtc, (RTC_DateTypeDef *)&time->WeekDay, RTC_FORMAT_BIN);
    ( R( L6 F5 k5 n0 M# O
  25. }
复制代码

" O2 G. w1 j# |3 U覆写闹钟时间回调函数:# `; \0 K' k8 z; B" M' F" S/ l  c" W
* X+ B0 k0 c& W5 N' u
闹钟事件的中断设置,要看MCU支持的是秒中断还是时间中断,比如10X系列,要通过当前时间去设置下一次闹钟,而40X系列的可以直接设置时间。
+ u* y- O& ^) L+ B. p
: b  }0 m9 K* {& o
  1. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc). f! R. u) M; c% L3 I: \0 J' f+ w
  2. {
    ) q* N% Z9 k  N9 ]7 T
  3.     RTC_AlarmTypeDef sAlarm = {0};
    , N3 ~6 b& F9 T1 @# y
  4.     rtc_time_t tim = {0};
    0 N# V2 Y2 B7 E" ?/ C0 x
  5. # h  [' [/ T+ z
  6.         // 获取当前时间, Q( Q3 s: g) q( h3 `9 W  X
  7.     RTC_GetTime(&tim);
    * o, C/ l6 R0 \$ |, q9 C: H& c

  8. 9 L- P" M% T# p
  9.     sAlarm.AlarmTime.Hours = tim.Hours;8 z+ m# y( m# ~, Q# j
  10.     sAlarm.AlarmTime.Minutes = tim.Minutes;
    : A" c  h( }% _+ R( }
  11.     sAlarm.AlarmTime.Seconds = tim.Seconds + 3;  /* 设置下次闹钟提醒时间是当前时间的3s之后 */0 o0 f1 e8 d. K0 a# _
  12.     sAlarm.Alarm = RTC_ALARM_A;. C9 n, o$ N. G0 Y9 |6 k2 U
  13.         
    4 k8 a1 o# B6 F* r& f5 ]: [
  14.         // 再次启动闹钟中断事件/ k6 E; B7 N) s2 g
  15.     if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
    & @, ^  K! I2 G! e! @7 H) h7 [8 F
  16.     {6 T$ Q) I# X! ~# r
  17.         Error_Handler();+ N/ a1 u6 o+ V$ ]2 l6 o7 Q
  18.     }
    : A: o! h! ^% z% g
  19.         - f! w) g. \$ }$ m6 Z2 P
  20.     printf("HAL_RTC_AlarmAEventCallback\r\n");$ L! h% z2 r% X3 T7 m
  21. }
复制代码
2 B+ ]; K% }2 q0 X! c" ]0 B
main函数:
$ g$ [* T9 W+ I4 ^. ?8 u8 i+ z  B" W. f
  1. int main(void)
    3 v) B1 R" v! p5 P
  2. {
    0 h+ r; t/ g$ j* s$ g. a- R
  3.     rtc_time_t tim = {0};
    2 E: u: e7 B$ T+ f
  4.         ) W0 ^, P0 W$ s. C& Q3 l5 b$ B
  5.     HAL_Init();
      Y/ J7 q" r3 Y5 ^4 U3 A9 H8 p
  6.     SystemClock_Config();' s, v! N9 h( U$ L
  7.     MX_GPIO_Init();8 R3 `; S' Z: d" d2 y
  8.     MX_USART1_UART_Init();) h2 h# o  K& T, Z
  9.     MX_RTC_Init();
    1 E. j( O. {* a5 g3 W
  10. , ]9 J: C: `- C  O& M6 I3 c
  11.     while (1)& w$ _# k. q7 u2 A) G; k
  12.     {0 i+ g  s1 z2 [
  13.         HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);. R  T/ x8 I6 g) N  p2 C" |
  14.         RTC_GetTime(&tim);
    # U; v, M: h* O% s$ q
  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);: B: C- C# n7 n+ Y
  16.                 HAL_Delay(1000);
    * r$ |0 J8 i; F% g. E$ P
  17.     }% C0 I* `" R! n7 B9 Y8 \* Z
  18. }
复制代码
3 t1 W  L, [5 c2 [9 `6 X+ _
(三)运行效果1 W  ]; `. v/ l, X. h5 ^( h

1 d. T/ D- }$ w- X4 i 20201225092230509.png 3 X1 k  F: Q6 Z  Q; d/ h0 b) B( f
2 m. C( K" G8 D9 @3 R
7 m% S; ?- l. t/ b
* a" ^6 D% g& Y8 l, l, ~8 |; s
收藏 评论0 发布时间:2022-4-10 17:01

举报

0个回答

所属标签

相似分享

官网相关资源

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