今天来玩一下STM32U0的RTC,后续想用U0做一个电子墨水屏的日历,正好要用到RTC,今天就先来摸一摸RTC是怎么玩的 % }4 `1 s( q& k& m0 q( z/ Z+ C
工程还是使用之前的模板工程 " ^+ [, x/ K# E% R
一、cube配置 开启RTC,把时钟源和日历都激活
' K* c! X8 E$ @6 Y 下面配置的参数基本上可以保持默认。这里面主要会改的参数是
4 w+ J3 ]" u( U/ ^ 其他参数保持默认即可 我这边年月日时分秒周几就偷个懒直接用默认的,待会儿我会尝试调用set函数改变其值,因为在实际使用时RTC都要用户自己去设置一下时间才正确 然后把时钟改一下,这个工程之前没有启动外部低速晶振,用的是内部RC产生的LSI,为了RTC更准一点,我要把外部32.768K晶振用起来。然后这边选择RTC Only的这个,因为我没有其他东西要用外部低速晶振,选这个可以在休眠时功耗更低
, h5 @9 c) U5 f, R8 \1 S
5 n. f, |) @4 x( \2 A2 _# ?4 O
6 a* l/ ] V+ b% e; f; Y l 最后生成代码(截图略) 二、代码修改 先来写一个获取RTC信息并打印的函数 - void print_rtc_data() ]' O& ^* m9 |. N' ~/ r# F
- {
d) Z, `' T+ z$ d$ ~ b# B - RTC_DateTypeDef sdatestructureget;
* ] x* D2 d, }0 q1 _) w - RTC_TimeTypeDef stimestructureget;
5 E) @; J2 a1 v0 k - 3 m0 c B5 t9 a! s' O
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);7 m. d" B1 {; f$ W9 Y. B
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
4 L: s7 p$ _8 v( g5 J: x8 P4 [( g - printf("Date:%02d-%02d-%02d WeekDay:%02d Time:%02d:%02d:%02d \r\n", 6 _( ?7 c# A0 k. z5 h, ^4 P
- 2000 + sdatestructureget.Year,; H1 d2 w0 n: f( F* ?* k) M6 h& Q2 }
- sdatestructureget.Month,$ |8 b) @) Y! u0 i( ^
- sdatestructureget.Date,% n# o. v! G( d6 [9 f) \: D
- sdatestructureget.WeekDay,+ {1 ]% ?1 v+ B2 q1 |
- stimestructureget.Hours,
5 M& U; K/ W. A1 v - stimestructureget.Minutes,
, |2 q9 W3 g$ C' }% P. Q3 j, q. R0 j - stimestructureget.Seconds5 d* G3 t7 g2 o# G
- );8 V3 Z4 _. t4 b5 V. ~" R
- }
复制代码
8 p0 h$ {5 Y0 v4 U& P- r2 q' K0 O; u 这边需要注意的是,HAL_RTC_GetTime和HAL_RTC_GetDate都要调用,不能只调用其中一个,如果只调用其中一个,那么后续再次调用get时间也不会更新,会一直获取到和第一次一样的数据 . ^1 l+ k0 E& ~/ o, j8 E7 T
把这个函数放到while1中,然后再加个delay,避免一直疯狂打印 - print_rtc_data();7 F- d: Q! v( f
- HAL_Delay(1000);' T& [9 j ~. t; W6 D3 G1 t, n+ X5 d
复制代码
+ q* f1 u6 R! H6 w3 O$ A
然后编译下载,效果如下
0 Z; J) A' V1 W% e
1 T/ i0 x: A r然后我们来试一下重新设置年月日、时分秒、周几参数 写一个设置的函数 - void set_rtc_data()
; b3 a" B8 u* R - {
- J5 w: f t1 y0 n$ [ - RTC_TimeTypeDef sTime = {0};
& T( G0 m3 W1 z8 U; t2 h9 o( p" ^& h - RTC_DateTypeDef sDate = {0};
, Z" v# |$ h1 n7 d: w$ v" \
7 r- ^" ?2 d8 w J2 _. S- / p! y# H; T4 ^+ O) s4 _' e) {
- sTime.Hours = 21; /* 21点 */
* o4 s2 G9 h/ d1 R- i8 n9 ^& T1 u3 j - sTime.Minutes = 30; /* 30分 */' l; x0 l: k1 H* \
- sTime.Seconds = 10; /* 10秒 */1 ^( m) T1 `& x- M+ d
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; /* 和初始化时的值保持一致 */; G1 c P0 x- P$ x8 U
- sTime.StoreOperation = RTC_STOREOPERATION_RESET; /* 和初始化时的值保持一致 */ ~& X7 g6 T6 r7 ?+ P! y [
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
; N( A6 H) S U3 f; F% X - {1 p `; Y C! `; Z' r& ]
- Error_Handler();
+ E. G' a$ Z$ Y; x- l; {" x- V - }* m0 z1 m/ ^! w; q/ a8 V
- sDate.WeekDay = RTC_WEEKDAY_THURSDAY; /* 周四 */
% V7 B7 P5 X/ P- v - sDate.Month = RTC_MONTH_MAY; /* 5月 */
* G6 Q$ S5 G# f+ f5 W - sDate.Date = 23; /* 23日 */3 s' G2 h# [; v! n
- sDate.Year = 24; /* 24年 */$ H, e: x) ]2 B, h6 C
& m3 e- k8 Y8 E6 y+ _9 z9 G- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)8 ?; b) E) b) `/ L
- {
4 L) A; U0 t8 r - Error_Handler();, B/ L' S7 }" C1 ]! i
- }
* N6 d7 j0 c4 ^9 z$ Q- p - }
复制代码
7 V! u$ D" G1 z
然后在while1中把它用一下,我上电后会让默认的RTC值连续打印10次,然后改变RTC的值,之后继续打印RTC的值 - uint8_t cnt = 0;2 \& E- T3 G5 ]: D1 K8 @( O1 u$ [9 O
- uint8_t flag = 0;
# ~5 W! J$ G5 x: U! }! N% n# W7 f
复制代码
% J5 \9 }! Z& d$ K; l
- if (flag == 0)! u- M$ l1 W+ R2 @4 Y
- {" q( c7 [0 `5 g3 i ^4 C0 A
- if (cnt == 10)$ G9 f/ d! ^) ^/ h2 f- D \
- {0 Q8 O7 T# V" d' X/ @
- set_rtc_data();" q! `* T% z0 B, d% o& }. t
- flag = 1;2 _ v. B+ c. ]% N. q; o
- }- {* t0 G( T* u! {7 T
- else
+ c; G8 f+ `. X6 ?" x& ^ - {; H5 y, u( y5 V* C/ ?; c# O
- cnt++;8 [- }' d5 m5 M* n! I( h
- }8 M/ V( ?5 ~4 k8 d4 q
- }
复制代码
/ X+ c8 w. F5 Z1 e9 ~ 然后下载,运行结果如图
# x- Y/ r! N V( P9 Q8 f' v: Z3 {
, D" N& K" W3 W3 X) A6 w5 d% B0 F' a |