STM32H750 的实时时钟是一个独立的 BCD 定时器/计数器,且带了日历功能,它提供一个日历时钟、两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。 此外RTC 还有自动唤醒单元,RTC还可以补偿闰年闰月等等,还有备份区域(BKP)写保护,这些这里不细说了。
4 g. H1 B. A/ L2 W* q9 E RTC 的简化框图- Z0 Z. d; {; F0 ~2 l- @2 E# _; @* L
- N- A, v! _5 K4 N! C
% R! _' j7 \" t0 D$ Q4 g! J$ N6 I
+ M& V7 L* e7 h$ C1 m! |+ p
时钟和分频STM32H750 的 RTC 时钟源(RTCCLK)通过时钟控制器,可以从 LSE、LSI、HSE 时钟三选一,如图所示,有两个预分频器RTC_PRER ck_spre 的时钟可由如下计算公式计算: Fck_spre = Frtcclk/[(PREDIV_S+1)*( PREDIV_A+1)] 图中,ck_apre 也可作为 RTC 亚秒递减计数器(RTC_SSR)的时钟。 Fck_apre的计算公式如下: Fck_apre=Frtcclk/( PREDIV_A+1) 当 RTC_SSR 寄存器递减到 0 的时候,会使用 PREDIV_S 的值重新装载 PREDIV_S,得到亚秒时间的精度是:1/256 秒,可以得到更加精确的时间数据。
5 C* a; [) d) A- i STM32CubeIDE 配置默认情况下是如图
, e: K7 t' P5 c& S o! O+ [
' i' j, N0 E$ e2 n
7 E- v8 |% N) S \& T: [9 I& y4 I( N一般情况下使用LSE,这里我们需要在RCC使能 4 l J6 I4 `, R3 i8 W8 d; h
' O/ W* V# w$ j+ X6 \/ G: k. k
2 }7 H8 N' z# j$ l( o然后在RTCC中使能时钟源,如果需要日历闹钟功能的可以在这里也使能上。. `6 T7 y6 m% \ J
! [2 ~7 u: Z0 {- I& h9 m+ t( S/ w
( n2 n" L" U+ L! D/ Q* @. r
: j, I8 c" L) e
公式如下: RTC时钟频率 = RTC时钟源 / ((Asynchronous Predivider value + 1) * (Synchronous Predivider value + 1))= 1Hz,也就是1秒 之后到时钟配置里面可以看到已经使能了
+ W4 x, E6 C) k
/ M* C: h/ F# T
) O& _. E6 U, z0 G, n. W
初始化 - static void MX_RTC_Init(void)3 v- p1 C. h+ O( \; z0 B
- {4 O2 Y$ q4 m) n
- ! G5 I. s5 l/ h) P. |6 ~* S& X
- /* USER CODE BEGIN RTC_Init 0 */5 l/ G/ s3 ^/ K2 v; o; G9 F" @6 m
- ) _4 {* V3 h2 J" M9 K& {" w" A
- /* USER CODE END RTC_Init 0 */5 C$ \. D: @, N" y1 \# ~
- / v ~) F& p1 {! I: Y
- /* USER CODE BEGIN RTC_Init 1 */
- r; `7 p/ M5 Z+ r" }" u
# G0 M% _# U0 g" _. C$ y5 P- /* USER CODE END RTC_Init 1 */
K/ W# k& {9 K g2 A - /** Initialize RTC Only; U$ ]5 ^/ [* F/ e2 [7 r4 N
- */
4 ^6 [! W2 I. {$ v" d0 ~# T: Z - hrtc.Instance = RTC;3 l) q" N) g% T% z
- hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
5 Y' r6 [4 ^( S - hrtc.Init.AsynchPrediv = 127;0 P4 y7 L: C( n. X; H8 B5 k
- hrtc.Init.SynchPrediv = 255;
6 ~" ~( u: V6 T2 E$ w# y* I# R - hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
8 H! E( l9 z8 c% _ - hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;6 p$ Y) \- C2 I t
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;) m0 b5 V! ?; B- O3 K% f7 \1 R
- hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
5 R5 @ r9 N+ _$ a; q - if (HAL_RTC_Init(&hrtc) != HAL_OK)
; ~8 k/ W" P8 y" [ - {
# C, F5 b0 U9 e - Error_Handler();% c. g% t$ R5 }
- }& U9 P& R) T7 r
- /* USER CODE BEGIN RTC_Init 2 */
9 ]% D" X) H( |3 ~! v0 z# J - 6 L, g& K+ i/ H e
- /* USER CODE END RTC_Init 2 */ R5 Z$ s2 v( f% s$ S" \0 m
0 b/ v: J1 S% P7 b- }
复制代码 # P3 T$ X6 s- |
. \ W9 |0 ^* T0 `2 Z" i可以看到outline里面有很多我们需要的函数,那么自己扩展就可以使用了 & |0 a" }" b; `+ Z X+ D% g! E
/ a: @' I( z l P. C
9 z5 t2 @" e' K' L
This function configures the hardware resources used in this example - void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
0 ?2 N8 s8 P' R S - {1 w% P% y; `" [$ }: K3 `+ C
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
$ \* l, E1 q% A; B7 `; C - if(hrtc->Instance==RTC) [. }9 r m/ x. Z1 ~. W" U3 T
- {
B5 a4 b3 h7 g$ Y+ {* v - /* USER CODE BEGIN RTC_MspInit 0 */1 J/ N& C- `8 y- L6 N
, V& {5 i7 C, z! }5 ~- /* USER CODE END RTC_MspInit 0 */$ |+ R- w& o; ]; a8 Z n1 }0 d
- /** Initializes the peripherals clock& \& X; D. [: \ i4 S+ t2 I
- */) H, a1 I, D/ j" Y) x6 d
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
5 l1 R2 b) R% p9 n1 g: ~ - PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;' H+ x8 Q4 l U* u* }9 K
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
5 L/ T* D) F2 P/ {8 x0 X1 {; u - {8 g( k- k! C, u% g& z
- Error_Handler();- s% j9 J8 a) Z/ w" j; \
- }
7 F8 v B, V' P3 H$ J% h% B
, p+ f# K+ q! W& B; j! ? S; s- /* Peripheral clock enable */
, m0 G" K# d9 U0 j8 U/ @ - __HAL_RCC_RTC_ENABLE();) ^. v8 G2 O5 k/ C* @
- /* USER CODE BEGIN RTC_MspInit 1 */) K( t! g% q: y$ U9 t+ Q, J
- 8 i; m2 z7 n% F. U8 K
- /* USER CODE END RTC_MspInit 1 */( K& w9 N/ O8 G p0 y$ M' P
- }. a9 h, X* l& h
! }# U# E# A0 u: C- h( }6 ]1 ^- }
复制代码 最后,可以按需定制自己的实现方式,RTC是特别实用的一个模块了。$ N/ s4 L9 k% X+ a) q1 L" R, C
% T3 \' K6 [! c# M0 @
4 M& d5 D0 g4 f7 |5 E* q, H, o: C6 k- \- C
作者:李肖遥
/ p: ^8 ~4 s9 M* u+ d7 m" R$ ` |