今天来玩一下STM32U0的RTC,后续想用U0做一个电子墨水屏的日历,正好要用到RTC,今天就先来摸一摸RTC是怎么玩的 ( g. u& b& ~/ h* C' Q
工程还是使用之前的模板工程
, r& t1 n( Z& O1 e; S) j/ g0 |一、cube配置 开启RTC,把时钟源和日历都激活
6 a3 F) M# l* B% V$ T' e+ U; a% g 下面配置的参数基本上可以保持默认。这里面主要会改的参数是
1 q5 M4 \* ?9 a p, E/ r- q3 I! |
其他参数保持默认即可 我这边年月日时分秒周几就偷个懒直接用默认的,待会儿我会尝试调用set函数改变其值,因为在实际使用时RTC都要用户自己去设置一下时间才正确 然后把时钟改一下,这个工程之前没有启动外部低速晶振,用的是内部RC产生的LSI,为了RTC更准一点,我要把外部32.768K晶振用起来。然后这边选择RTC Only的这个,因为我没有其他东西要用外部低速晶振,选这个可以在休眠时功耗更低
. U4 J2 x* @& [% G. s5 _( s
! ~. C0 ]3 A" b6 q) m3 Q+ [
D9 o' R' j' ]. ?7 n) E" ~& ? 最后生成代码(截图略) 二、代码修改 先来写一个获取RTC信息并打印的函数 - void print_rtc_data()9 T* @2 G `+ K6 w4 L' |. ` [0 R
- {: P9 G- G" T4 a; t, ^8 F
- RTC_DateTypeDef sdatestructureget;
( B5 Z3 `! V& G: b& T/ a - RTC_TimeTypeDef stimestructureget;
0 ~' e1 n8 r9 F8 m% H7 |/ @) V - " ? E# G* d7 ^0 x% u. V& R
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);0 X) M- Q" }1 W- q6 N/ ]% I
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
7 f& b* `- d! x. c# u. p* ~ - printf("Date:%02d-%02d-%02d WeekDay:%02d Time:%02d:%02d:%02d \r\n", # w8 r5 R4 Z! { E7 [
- 2000 + sdatestructureget.Year,
0 r0 r1 V+ Z0 z( r" |2 Z - sdatestructureget.Month,
2 C3 M& P6 I9 }5 e0 T5 Q0 h - sdatestructureget.Date,+ K; y2 Q" h! Q; a0 N
- sdatestructureget.WeekDay,9 H3 _" r" D9 [5 u/ G+ Q
- stimestructureget.Hours,4 b4 p, j* h) ]: h. G% B
- stimestructureget.Minutes,
- a- J w$ W0 f( `% ^. E6 y7 V - stimestructureget.Seconds% x$ D8 d. {7 _
- );+ U, x% a8 G% i
- }
复制代码
2 @/ r* i7 M( @# ] 这边需要注意的是,HAL_RTC_GetTime和HAL_RTC_GetDate都要调用,不能只调用其中一个,如果只调用其中一个,那么后续再次调用get时间也不会更新,会一直获取到和第一次一样的数据
, f7 A; K+ _ s) C& _( c把这个函数放到while1中,然后再加个delay,避免一直疯狂打印 - print_rtc_data();
( Z! V0 s4 K( w/ z# o - HAL_Delay(1000);
$ Q7 Z' ?. L8 V; v; d( Z
复制代码
" V5 b G7 _0 A. q 然后编译下载,效果如下
6 U1 Z& H( J2 k4 ~* P: h7 w' J - v) l1 C+ p2 ^5 X* d
然后我们来试一下重新设置年月日、时分秒、周几参数 写一个设置的函数 - void set_rtc_data()
6 x2 [" {# `5 _+ L - {# m! |, k- Z/ Z& ]0 A
- RTC_TimeTypeDef sTime = {0};
+ h' X- a: a' h6 M2 _$ ] - RTC_DateTypeDef sDate = {0};
& q# r; c* y% n
, J7 k. p: r+ v- 2 n* \: M8 m9 h# x1 b" }& @
- sTime.Hours = 21; /* 21点 */4 z& H: T5 t; K' m6 X/ Y! ]' z7 S: y
- sTime.Minutes = 30; /* 30分 */
: g V) c4 U/ K" I+ e2 ~ - sTime.Seconds = 10; /* 10秒 */' a4 N- G" M! ~1 _& E
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; /* 和初始化时的值保持一致 */, f" p9 R. s( V
- sTime.StoreOperation = RTC_STOREOPERATION_RESET; /* 和初始化时的值保持一致 */6 d8 i& X A' K0 Z
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
9 b# b; R- y% n8 E - {
" W% c4 z$ ?1 F - Error_Handler();! a* I+ R3 w6 Y/ ~% b, W
- }
& E! _; \0 f. Q. V1 V - sDate.WeekDay = RTC_WEEKDAY_THURSDAY; /* 周四 */" f9 v% D) E# |& D- l
- sDate.Month = RTC_MONTH_MAY; /* 5月 */+ ~1 ^- Y/ i7 {9 D4 q! V
- sDate.Date = 23; /* 23日 */
3 o% t' f+ Y8 F1 x - sDate.Year = 24; /* 24年 */% D, g. b3 s- J
4 ^2 T# f! G6 R6 p8 p6 q1 A( u0 @- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
. F5 {% g' K0 u6 t9 Q - {
. K% N# q1 |; b7 b - Error_Handler();5 s1 O3 f/ a, }* c
- }
. I/ Y0 ?+ v2 ~ - }
复制代码
+ m' {7 U" X% e
然后在while1中把它用一下,我上电后会让默认的RTC值连续打印10次,然后改变RTC的值,之后继续打印RTC的值 - uint8_t cnt = 0;( x y9 h) R9 {! H* \- H
- uint8_t flag = 0;2 @- D( o) z9 B
复制代码
8 `: i; N! Z5 u4 Z
- if (flag == 0)! q/ S) H& R: {6 ~1 W' O+ E' B
- {
2 U, f3 R4 b6 T7 r6 X' C$ a& Q - if (cnt == 10)# [+ [0 j/ ^3 _4 y4 T9 Q/ g
- {
6 a- g! `: D3 R/ F, ^" p - set_rtc_data();
$ Y! r0 A* m/ P$ w5 _! O - flag = 1; _3 h @9 i. O7 E5 w6 F
- }
; `/ V7 O) |* r4 U4 W. z - else$ Z0 b, A- |' T' r* l0 J
- {
W" T. k7 H7 J1 E# H- s - cnt++;
. k3 g% I$ o! V) T) A2 H, ? - }
+ B/ c1 x4 ]; u- q* g - }
复制代码
0 h3 O; { F* \+ E
然后下载,运行结果如图
5 S9 X: Q+ |1 m) o
% v# q& z) ^2 Y6 \$ ` |