|
今天来玩一下STM32U0的RTC,后续想用U0做一个电子墨水屏的日历,正好要用到RTC,今天就先来摸一摸RTC是怎么玩的
% E8 x. H# k* d2 Q! z7 Z工程还是使用之前的模板工程 ; }; v1 ^" g% ~ ~) Q4 f# n
一、cube配置 开启RTC,把时钟源和日历都激活
d! ?3 e" U9 k+ q6 V 下面配置的参数基本上可以保持默认。这里面主要会改的参数是
$ ~. @6 O& V- g! S" K/ g 其他参数保持默认即可 我这边年月日时分秒周几就偷个懒直接用默认的,待会儿我会尝试调用set函数改变其值,因为在实际使用时RTC都要用户自己去设置一下时间才正确 然后把时钟改一下,这个工程之前没有启动外部低速晶振,用的是内部RC产生的LSI,为了RTC更准一点,我要把外部32.768K晶振用起来。然后这边选择RTC Only的这个,因为我没有其他东西要用外部低速晶振,选这个可以在休眠时功耗更低
( x/ V4 w6 r: p. b0 s" T/ x/ z / h' h; A8 C- ?/ J- u7 k
3 {$ s" u0 {% B" g. v ? 最后生成代码(截图略) 二、代码修改 先来写一个获取RTC信息并打印的函数 - void print_rtc_data(), \* ^! k: t3 V/ c, h
- {
& r& j- C" n+ r0 R1 h - RTC_DateTypeDef sdatestructureget;
" O0 e. ^; M+ W' S - RTC_TimeTypeDef stimestructureget;: V( R5 [+ Z+ m7 |
6 B& R8 O2 D+ `7 Y: D- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);- z) b: ]% s$ d! P4 s0 ^3 d8 F7 z
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);& a5 O: j( d5 J/ [5 N6 l
- printf("Date:%02d-%02d-%02d WeekDay:%02d Time:%02d:%02d:%02d \r\n", ( w, n2 N" X" T2 x0 x, }& l5 s: m6 q
- 2000 + sdatestructureget.Year,
: {7 O( r# M& v# Q# ^) b! E: Q - sdatestructureget.Month,
, P! _6 t4 @5 e0 `: ^% C% r* e; h9 r5 L - sdatestructureget.Date,
: f5 k F& K4 w5 b$ d4 J5 h' e! q - sdatestructureget.WeekDay,! `5 c+ Z; |1 y) m' R* x/ r
- stimestructureget.Hours,9 Z( y0 G* s2 X, p [' x9 j
- stimestructureget.Minutes,
/ h- G; |6 w* W N q4 G: W& N - stimestructureget.Seconds
* f7 v# i* }) c; [ - );
- ~1 M# ~; v1 I9 E9 u* s - }
复制代码
- N* ?8 b9 w* V. @. \& K" @ 这边需要注意的是,HAL_RTC_GetTime和HAL_RTC_GetDate都要调用,不能只调用其中一个,如果只调用其中一个,那么后续再次调用get时间也不会更新,会一直获取到和第一次一样的数据 - t4 t/ q9 h; X- U) n
把这个函数放到while1中,然后再加个delay,避免一直疯狂打印 - print_rtc_data();" y, w3 w6 U8 W8 w0 p9 X
- HAL_Delay(1000);1 S/ X! d' P( w0 n( p8 J
复制代码
9 i3 S8 z# q/ q. h1 U+ G' s5 r 然后编译下载,效果如下
" M) `5 Z {- S+ O' W; H5 m; A+ E5 u
0 w) Z: m$ |$ D- ^# V8 `
然后我们来试一下重新设置年月日、时分秒、周几参数 写一个设置的函数 - void set_rtc_data()5 W6 k3 R z$ Q3 s* A
- {
2 }* U! ^* }) K; e: F - RTC_TimeTypeDef sTime = {0};
+ X6 d' H4 m2 k% w - RTC_DateTypeDef sDate = {0}; H' T8 x u3 @9 q7 o/ F+ T" V
- 6 H. v( W5 m4 {7 l7 |+ q0 ]) K
& q- q$ z5 ?/ S0 ~$ P- sTime.Hours = 21; /* 21点 */2 r" S4 U/ E! x4 O$ E3 c" B
- sTime.Minutes = 30; /* 30分 */
( q4 D( ?! Q4 F: ^" n s - sTime.Seconds = 10; /* 10秒 *// i" F: X0 G: |% r) [' R1 i
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; /* 和初始化时的值保持一致 */: Y E Y. _- \' e5 d
- sTime.StoreOperation = RTC_STOREOPERATION_RESET; /* 和初始化时的值保持一致 */4 V0 j0 z/ K# m% j9 t
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
5 ]$ N6 k) z1 k! S- k3 y# `& Q - {
7 d8 J- J- X) q( Z; w& K - Error_Handler();
4 e" u" E" D" ?" a5 z$ n+ L% H - }# X! \* h9 [: d M3 a( `0 u2 w: \
- sDate.WeekDay = RTC_WEEKDAY_THURSDAY; /* 周四 */
+ \8 A* u- Q+ B$ @0 l - sDate.Month = RTC_MONTH_MAY; /* 5月 */9 d$ R9 s6 i7 f; Z; h
- sDate.Date = 23; /* 23日 */ G$ u$ E- h$ v- _7 b! _
- sDate.Year = 24; /* 24年 */6 M/ q1 g; f6 R6 G. |) S
" Q) r9 t, U9 U6 ~. {3 r/ q8 s- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
3 A( H. g6 y4 u/ j3 X$ q! h8 K - {0 G! a1 L7 i+ h$ b, C6 O$ a
- Error_Handler();) H/ g6 Z/ q: o M; e0 V
- }/ v( W! P; |* @5 z0 g) W
- }
复制代码
6 q: ^( @1 t4 r! Q 然后在while1中把它用一下,我上电后会让默认的RTC值连续打印10次,然后改变RTC的值,之后继续打印RTC的值 - uint8_t cnt = 0;
9 x; c( {$ C* k6 o1 r+ h - uint8_t flag = 0;
( e+ s" {& J. \$ p3 X- R
复制代码
, X: ~* W3 F1 ^' ~9 z; i - if (flag == 0)
% s4 a( |5 B. j: S2 U9 L - {9 X) {8 N+ q3 v+ n9 F5 `$ b
- if (cnt == 10)
; L) u/ d5 L/ x* r- w! M" v& T; H - {
3 f- w+ g1 M G' `3 @8 Y - set_rtc_data();
# \1 j$ C% i/ i* |3 A - flag = 1;
! t' B+ T6 ` u }; |+ y$ ? - }6 K: P1 D3 t1 i) M$ q2 H
- else! U4 k6 ~7 h$ E( G
- {
' a/ }0 ~/ m0 i* f7 o5 C$ y; \$ o% G3 K - cnt++;- B" e( E# k* b4 D1 b
- }
7 N% o3 Y6 W3 ~+ E, _- h0 Q - }
复制代码
5 } c6 }, G" K0 ]! R
然后下载,运行结果如图
6 ? W5 i7 H4 P L& Q ! O5 a1 l; W! K \+ x
|
感谢分享