实验目的:
7 p' C3 r, B) d# j4 I- X通过STM32CubeMX进行简单配置生成HAL库实现内部晶振RTC。8 a" h% J7 ?- ]
( ?8 c9 w5 P$ w# L; f q2 N. r一、STM32CubeMX配置如下:
% ~! S- A& `4 Z# F4 X1.时钟树配置:
' s; l9 f& O% D2 j因为板子没有外部RTC晶振,所以只能使用内部32KHz晶振,时钟树配置如下:
2 ^4 |1 H+ h& Y1 v d: K
0 W1 n5 ?/ \6 N, X- S+ d7 V
2 \$ {4 k2 z* G- Y3 g A8 ?+ i: _: a6 h4 G- `* {
2.RTC配置:
; c) l! P o* b# M5 g
3 v. ?2 [ ]1 o
0 q8 ^7 r* ]2 l0 m7 h0 z# j- A, x4 M& g4 w; F0 i6 F+ b7 b
(1)关于Asynchronous Predivider value 和 Synchronous Predivider value填写多少,请看下面:, {: Q! ?( B. n; `
- }! f' G, q# a8 z& D8 D9 j' Y8 {2 p' n1 Z
1 \* F: L4 F K1 S
/ j# N7 Q S* c
/ u: P9 V$ W0 G( j3 S因为内部晶振是32KHz,所以毫无疑问应该选择LSI=32KHz即:
2 `4 L: o! }& {0 U6 B. d+ N+ g+ y" H% ~7 x3 e
Asynchronous Predivider value :127% ^# { M& d% @; F
Synchronous Predivider value :2492 n7 c4 V6 P+ m7 z
' P: E+ [- s) ^6 g8 R(2)关于Hours、Minutes等这些初值没啥好疑问的,直接填写,但是Year需要注意一下,它是从1970年开始算起的,所以比如填写50就是2020年的意思。8 z/ Q1 |1 g, k( }9 ~7 O
二、STM32CubeMX配置生成的HAL库如下:
# x% k' b4 q0 ^9 |' [. S. \- /**1 ?$ V& ]+ f; u5 |( ~! `3 K0 j* M
- ******************************************************************************
$ d* [" d& H& s+ F6 |0 k0 C - * File Name : RTC.c3 ]1 B! w9 k- r* L; j! h
- * Description : This file provides code for the configuration
# S; b: Y( U) G; R( d - * of the RTC instances.
1 u1 T3 U" r7 E: @4 w - ******************************************************************************
0 o8 V7 I/ s( `1 {9 } - * @attention
& Z0 f$ D! {" S/ G& A% n - *
: E) C" w" B" ~# s* ^! K: z# H - * <h2><center>© Copyright (c) 2020 STMicroelectronics.
1 O7 @: A$ Z- O8 h - * All rights reserved.</center></h2>
9 r5 I2 }0 r5 {* |( a( ^ - *% c; r& }+ ]+ X, i
- * This software component is licensed by ST under BSD 3-Clause license,1 v4 f( s+ y/ T! P8 t$ a
- * the "License"; You may not use this file except in compliance with the
. V, H" g+ T, _8 x' ^/ W% ^, n - * License. You may obtain a copy of the License at:8 G3 |# R, t# m( ~9 i; e/ O& g
- * opensource.org/licenses/BSD-3-Clause
K8 R2 ]1 l& Z- n5 h+ U6 X4 e; I) x - *
V- o" \) U2 I - ******************************************************************************: f; w8 T- l8 k6 g9 @: b' `
- */) D, M3 g( o4 V/ v
- / F5 ?* K3 M# y* a
- /* Includes ------------------------------------------------------------------*/
# [ q* v( N4 ?# T" n - #include "rtc.h"% G& U* r9 k2 U9 b' R) a" A
- 1 _0 |' V( C$ {2 d
- /* USER CODE BEGIN 0 */4 s3 m. L/ [/ C: e$ y
- RTC_TimeTypeDef GetTime; //µ¥Æ¬»úÄÚ²¿RTC¶Áȡʱ¼ä
; _7 N: e$ k) i& B - RTC_DateTypeDef GetDate; //µ¥Æ¬»úÄÚ²¿RTC¶ÁÈ¡ÈÕÆÚ
: z3 F/ ^% R3 i5 N$ J' [ - uint8_t RTC_READ_Flag;- U* t0 ~) j1 T! M$ i1 V/ v9 t
- /* USER CODE END 0 */
# z8 i( i* _; `. D+ i4 v - ; I0 u) k: I2 w0 h, u
- RTC_HandleTypeDef hrtc;& p$ I! k9 S* t) L) w) J, K
! i& h- G6 Z8 ^/ i- /* RTC init function */
! n6 }$ h) H8 ?! |1 \ - void MX_RTC_Init(void)
; V+ A3 @4 q1 W% [) n: V5 ] - {5 i6 g# i: v0 K! r* L2 `+ x) R
- RTC_TimeTypeDef sTime = {0};
1 d+ _( R' H. U; j1 F! j+ r5 Y - RTC_DateTypeDef sDate = {0};
, d# y% [& N! {
6 d: p8 T/ i# B; A3 _- /** Initialize RTC Only 7 ]7 `. y. X; g x* a( ]
- */
+ Q' x q; |: Q; b* P" H - hrtc.Instance = RTC;
' {0 \' J" n; }' p5 w# E# J - hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
5 { d) ?- G1 b# K. \, S* P) Y - hrtc.Init.AsynchPrediv = 127;4 P1 h3 v4 I ~ }, _
- hrtc.Init.SynchPrediv = 249;
6 q7 Q A6 B( z1 S( f+ t, a - hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
' I4 l# j: j6 o) z9 K& Y h# | - hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
" i% w0 ], S: \ - hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;- m( ` C2 k; u
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;5 O1 k2 w+ e+ r- ~6 W6 J6 V
- hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;1 b* q# S5 I* t# c
- if (HAL_RTC_Init(&hrtc) != HAL_OK)
! d9 n* g0 \+ c/ G/ g: Y - {
! }; s: U1 C* ~% o - Error_Handler();3 D% [# B d7 l H$ m& U7 A
- }
# @# D$ z0 I' i, ?( } - ]; z# A/ }1 f$ y9 {8 w* x% `
- /* USER CODE BEGIN Check_RTC_BKUP */ b# O' E2 f/ I! H" I
- 7 g# U5 m4 l% B" v3 B* i
- /* USER CODE END Check_RTC_BKUP */6 B7 B2 E' z' z6 Y; _, Z+ |
- $ B2 A$ w1 P7 h0 V( k! L
- /** Initialize RTC and set the Time and Date
4 W4 u6 U/ R _5 b5 k, P* D, K - */% f9 o) B% V1 Q; F6 h ]- [
- sTime.Hours = 19;, @! d) m" T' T
- sTime.Minutes = 07; \! N3 l% t1 N& m. X
- sTime.Seconds = 00;
$ A' g, x$ i, {; y3 A# S; p! p - sTime.SubSeconds = 0;
: k9 X, h. U0 |9 y6 K - sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
. z: W2 e; f6 @" I - sTime.StoreOperation = RTC_STOREOPERATION_RESET;6 m2 h k7 s, R7 I
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK); o+ ^- e& [5 |$ }
- { S9 W5 d8 n$ O
- Error_Handler();
4 {" B1 E/ l) n# t - }
! h* q/ _ o8 [ - sDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;9 K- Z' p2 J- d, T" h- E
- sDate.Month = RTC_MONTH_SEPTEMBER;
1 _; _6 k" f( l# j/ Y4 q6 K3 f - sDate.Date = 8;
I/ j+ b& n3 a. k% F% i( x - sDate.Year = 50;/ _# X/ C" T4 `9 W2 p/ O
- ' h1 D3 p4 L& i- z
- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
& ~# V: l7 F! R U9 z - {* V: d% z# I+ J
- Error_Handler();
* M' {. ^2 k: T0 }8 Q* O - }
6 M; B' j& {% l4 J2 a8 g2 Y
7 Y8 c& x, C5 ? I8 r; k, @9 f- }
( P" Z1 D" U$ N4 S' @0 S+ B
4 P7 `0 z2 @0 c0 z- void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
5 c1 Q6 B. X. ]& R7 D - {
: D# U' Z. c8 e; v2 G - 5 ]2 ^5 b" d2 `6 v( R
- if(rtcHandle->Instance==RTC)- a# c- f/ G9 }! T3 m" i2 F
- {6 Q; A& M6 r4 n5 M: k( p
- /* USER CODE BEGIN RTC_MspInit 0 */- O9 ^+ {5 z- Q& N# s# t: e; M- E2 P
" b7 x8 w: m8 y7 n4 W# ]3 \! ~- O- /* USER CODE END RTC_MspInit 0 */
# t$ q; v7 N6 G8 J) B* J: i - /* RTC clock enable */
7 _' ~6 C0 b- E1 G5 ] - __HAL_RCC_RTC_ENABLE();1 u9 L% x$ c" _+ T
- __HAL_RCC_RTCAPB_CLK_ENABLE();3 m# C) _. U6 L
- /* USER CODE BEGIN RTC_MspInit 1 */
5 S: _2 N o. y0 R" B* M - 3 ^9 Y9 s0 j4 b% c W! S
- /* USER CODE END RTC_MspInit 1 */4 Z6 A& U. f# R1 \+ x/ l! @
- }7 S8 L, d: E2 k
- }) ^) y7 r6 |" ` ^
9 Q: E" H U' g# ^- void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)6 f% U0 Z( ]6 Z/ [ X- T9 `% f) w% |
- {
+ z! }; l. W# c9 }
* p# ^6 d9 t! k( m5 K- if(rtcHandle->Instance==RTC). x+ p3 n, T5 p# H' ~9 ^9 _
- {
: j1 U# B1 [% S0 L" ]& u8 k( a' @. q - /* USER CODE BEGIN RTC_MspDeInit 0 */* J1 Z4 y& }) s7 j
; B3 ^/ M4 v' r1 S- /* USER CODE END RTC_MspDeInit 0 */. w# e6 Q0 x8 \- q# s
- /* Peripheral clock disable */. p2 N: [1 q; t9 a
- __HAL_RCC_RTC_DISABLE();
7 D9 d* y- e" r2 _! P9 [ - __HAL_RCC_RTCAPB_CLK_DISABLE();
9 Y2 X/ Z0 y' U R- Q8 b - /* USER CODE BEGIN RTC_MspDeInit 1 */0 A! Z/ e$ n. p% k/ Q% T
- $ S" U$ d) {! \! n5 L" d, f1 h- w9 c: z
- /* USER CODE END RTC_MspDeInit 1 */% y; _) z* N2 \( C ^7 g
- } A3 H' `( q' _! N, E" k4 i
- }
复制代码
, O. X& ^1 C9 \9 I" K* L% o) u 5 Z U [5 x$ o: ~) g" n1 E
三、时间日期获取设置等:2 p, X! P; F# }& W$ { ?) @
1、自己重绘一个设置time的函数:
. F& p! |# ?0 D$ T- Z B3 A- /* USER CODE BEGIN 1 */) {% y' P/ |. u& ]% {
- void RTC_SetTime(u8 hour, u8 minute, u8 second)2 m1 _; k+ B; E8 u9 ?$ S% n
- {
3 }+ M9 N1 t2 ?5 g- ` - /*##-2- Configure the Time #################################################*/
/ v( d5 [5 S: _2 X - GetTime.Hours = hour;4 d( B5 G6 p" v5 ?, ^& }' N
- GetTime.Minutes = minute;
+ Z X! m8 S( V \! N - GetTime.Seconds = second;
. c) c4 W6 B8 {! i S - // GetTime.TimeFormat = RTC_HOURFORMAT12_AM;
5 B& u; ?, v% {# d2 X - GetTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
2 h, D/ o: `9 V1 W) k - GetTime.StoreOperation = RTC_STOREOPERATION_RESET;
$ L/ v% }' j( m% n7 m - / W" i/ c3 Y+ z) R7 L# _
- if(HAL_RTC_SetTime(&hrtc,&GetTime,RTC_FORMAT_BIN) != HAL_OK)/ _0 T- D% I) \+ b
- {
; y5 ^, [- P. p" l* o5 H7 O - / [8 G* M0 r' u% L' W' H9 Z* ]
- }, r9 G: y3 n: q/ r& p4 r2 p
- }
1 w7 B# U' j8 B7 W% x - /* USER CODE END 1 */
复制代码 ) I' Z$ C- D2 _* r
2、调用函数实现RTC:. j8 O9 {5 \" A& S
1.首先初始化RTC时钟:& G/ Q2 O: }, M( u9 ?# V! n
. ~% S! ]0 t3 u1 J& O- n4 N2.接着设置time时间:( z1 H7 g. G2 b( l6 J* d2 n
- RTC_SetTime(11,59,50); //设置时间为11时59分50秒
复制代码
, L$ V6 K+ f$ Q3.然后调用HAL库函数实现time和date获取,有个细节要注意一下,需要先获取日期再获取时间,亲测直接获取时间会有问题:
: {: k2 p# [' J+ E- HAL_RTC_GetDate(&hrtc, &GetDate, RTC_FORMAT_BIN);//更新日期% E. F- a1 U( n+ n
- HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);//更新时间: Q# h: Z3 k Q, |# H# o
复制代码 4 _# _" T6 d2 S3 I* G" K: z5 t& o* b
|