|
今天来玩一下STM32U0的RTC,后续想用U0做一个电子墨水屏的日历,正好要用到RTC,今天就先来摸一摸RTC是怎么玩的 . r: [& {9 D- X' j$ q
工程还是使用之前的模板工程 5 n+ r3 T3 o$ B
一、cube配置 开启RTC,把时钟源和日历都激活
) Q6 x' S6 H8 N+ F, } 下面配置的参数基本上可以保持默认。这里面主要会改的参数是
* }# g; ]+ Z# _, y9 i
其他参数保持默认即可 我这边年月日时分秒周几就偷个懒直接用默认的,待会儿我会尝试调用set函数改变其值,因为在实际使用时RTC都要用户自己去设置一下时间才正确 然后把时钟改一下,这个工程之前没有启动外部低速晶振,用的是内部RC产生的LSI,为了RTC更准一点,我要把外部32.768K晶振用起来。然后这边选择RTC Only的这个,因为我没有其他东西要用外部低速晶振,选这个可以在休眠时功耗更低
7 g3 Y" S$ w% d5 L0 h$ b) [5 Y9 t+ r 6 p; x( R" I) p \2 `5 X
! k9 ]* ~# d. A6 o
最后生成代码(截图略) 二、代码修改 先来写一个获取RTC信息并打印的函数 - void print_rtc_data()
, y' v5 M6 C; @+ Q; M - {
$ P( z5 L# B9 G N1 j- p+ H - RTC_DateTypeDef sdatestructureget;
" Y: K1 I7 P/ i$ V - RTC_TimeTypeDef stimestructureget;5 H% ~1 N3 u) [/ [" S0 P
3 K7 a0 k; a& m0 o7 ^- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);3 b1 W+ V, P2 L' j B8 ^( L; K* |
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
3 T! p7 ]" }" @ - printf("Date:%02d-%02d-%02d WeekDay:%02d Time:%02d:%02d:%02d \r\n", : }, H8 f$ ^1 E/ o' k; C/ y/ `
- 2000 + sdatestructureget.Year,
; V! q: \& ]" I2 W$ B5 n - sdatestructureget.Month,5 q# H7 F I, M& g
- sdatestructureget.Date,
* B- z4 G: r9 i1 o2 L7 r+ L5 ? - sdatestructureget.WeekDay,0 y- v, n/ U5 @2 P) t* a3 A
- stimestructureget.Hours,
- u; [6 y/ a4 J5 U) N - stimestructureget.Minutes,( u8 @" v% k+ F8 T6 t& i
- stimestructureget.Seconds4 R- W s, X& Q/ G. F1 I
- );
$ |! _& |8 A* S2 ?) ]; J+ Y - }
复制代码
; v% f$ H8 E( { I: Q 这边需要注意的是,HAL_RTC_GetTime和HAL_RTC_GetDate都要调用,不能只调用其中一个,如果只调用其中一个,那么后续再次调用get时间也不会更新,会一直获取到和第一次一样的数据
6 \9 D, W! @/ I0 p3 g' S4 Z# X# Q/ l把这个函数放到while1中,然后再加个delay,避免一直疯狂打印 - print_rtc_data();6 J' z' N s. s: o/ A
- HAL_Delay(1000);
$ A! ~. ]) e3 ?
复制代码
f/ y: `" T Y8 W2 b 然后编译下载,效果如下
. G# M* X) `3 q1 @
3 ^% G! @6 i# W' b1 A然后我们来试一下重新设置年月日、时分秒、周几参数 写一个设置的函数 - void set_rtc_data()1 [1 z7 Q0 K# \* X& z% u' b# R
- {' C( }7 P6 R; E- _7 ]) B/ x4 ^
- RTC_TimeTypeDef sTime = {0};: Z: V/ E4 q: U; R* f
- RTC_DateTypeDef sDate = {0};
7 d1 S+ r2 [$ x" q3 A8 k* a
* p1 a7 W; T+ V2 j8 e- 6 V4 ^+ a- T6 c
- sTime.Hours = 21; /* 21点 */3 x) v% W; |6 D& h4 G* `9 i
- sTime.Minutes = 30; /* 30分 */
2 |- f" ~& t$ M - sTime.Seconds = 10; /* 10秒 */( e* Y! M3 w: V8 o& ]
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; /* 和初始化时的值保持一致 */) W. F+ `( }2 p# I: L) j
- sTime.StoreOperation = RTC_STOREOPERATION_RESET; /* 和初始化时的值保持一致 */- x) W# u6 I L, ?' Y2 q1 _
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
/ {5 l, P* F9 J0 K( P - {: d& l" h: K* D: g# Z
- Error_Handler();
1 l& f. j, k. N3 S - }3 ~2 \: n+ f. _
- sDate.WeekDay = RTC_WEEKDAY_THURSDAY; /* 周四 */
; |2 P# R0 X2 @" D - sDate.Month = RTC_MONTH_MAY; /* 5月 */+ p. Y$ c3 i8 H
- sDate.Date = 23; /* 23日 */
' A" r. p: n1 f% q' Q7 P/ X. R) u - sDate.Year = 24; /* 24年 */
1 [8 z @0 |- Y! w$ j
) T) ~5 _" q! c4 e! M- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
" m8 n& i9 Y% f* B+ Z } - {
3 T0 @. k8 V' b+ O; J7 B. ^, l, @* H6 p - Error_Handler();7 n* d+ [5 |/ B Y
- }
N* d8 x d# V5 e6 T - }
复制代码
9 T, [! h! m E
然后在while1中把它用一下,我上电后会让默认的RTC值连续打印10次,然后改变RTC的值,之后继续打印RTC的值 - uint8_t cnt = 0;
; L, V. | u8 z! Z o+ o - uint8_t flag = 0;" A7 i! Z0 e3 K
复制代码
- C( G7 Z: r& i: D# h" K [ - if (flag == 0). |; o, _2 B' X
- {+ m3 y' k; w- ]* r# ^
- if (cnt == 10)0 o; V' U: i1 o: E" n1 b/ `: O
- {
. {$ f {6 B' X - set_rtc_data();
4 n5 ?9 V: S1 Q8 P - flag = 1;
0 v. }. O" m1 f: x - }
) D7 h8 V5 u3 d - else
6 z# u+ T8 u8 o+ g, ]. \# H# @0 ~' O - {
" j0 r& F8 F! [9 m L9 t; t! O3 ?6 C6 m - cnt++;
% F' M) T1 L( o# Z# S7 f5 s - }
1 _& M7 s: j( J0 R M - }
复制代码
' Q$ n" I; S, D 然后下载,运行结果如图
" G: u( D$ {3 r. v# Y( L
/ g& w. U% ~5 \" P1 ?" x- O
|
感谢分享