STM32H750 的实时时钟是一个独立的 BCD 定时器/计数器,且带了日历功能,它提供一个日历时钟、两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。 此外RTC 还有自动唤醒单元,RTC还可以补偿闰年闰月等等,还有备份区域(BKP)写保护,这些这里不细说了。
5 V1 l$ ^$ Z; g' | RTC 的简化框图0 `. V" J8 j4 a& a# a
$ z8 q" u0 |4 K+ R8 C* ^
( Z: |; j$ X0 V+ A( p
/ x$ n8 W3 f8 }时钟和分频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 秒,可以得到更加精确的时间数据。
& ?. t- o. j7 L STM32CubeIDE 配置默认情况下是如图 , _ D+ U. ~6 z/ J& T9 ^
/ [8 ^. q+ Y7 C5 G3 f6 W5 Y, y( R0 {
一般情况下使用LSE,这里我们需要在RCC使能
/ h% x: E0 _; |
; j2 f% ~, n- w7 B* N+ p$ ^0 o6 T _7 `. p: t4 r/ m% a
然后在RTCC中使能时钟源,如果需要日历闹钟功能的可以在这里也使能上。" g% W Y% s) b4 q9 U2 o
8 o+ ^2 ?* f, Q; H8 K) n& m
$ K% x& N. Y+ Y0 h, A
, t3 n6 W4 e% u) @" Z5 U1 W. N: C/ Z" U, S1 N
公式如下: RTC时钟频率 = RTC时钟源 / ((Asynchronous Predivider value + 1) * (Synchronous Predivider value + 1))= 1Hz,也就是1秒 之后到时钟配置里面可以看到已经使能了 - F+ Z/ x& _4 T& n7 C
2 R5 ]( q+ K9 r' u) l
* w8 Q% N$ _# C& ?" Z' W# D* r4 E初始化 - static void MX_RTC_Init(void)
% S! t. a9 V4 }8 I6 V - {( C1 y: `. Z; J: K0 G+ E' K' f' X7 O
- : P# D* {! i/ D( T( h
- /* USER CODE BEGIN RTC_Init 0 */
" x3 g" J' r/ r$ C- [! K
. [" e, C1 f9 A7 L- /* USER CODE END RTC_Init 0 */
5 M8 D$ b' i$ K, F+ n6 U+ E: o
; H. l! B2 h3 S9 m3 x& T& B: O- /* USER CODE BEGIN RTC_Init 1 */9 T4 Q* o" x2 _. I* c
! g2 l5 E) q) F/ s- /* USER CODE END RTC_Init 1 */
a4 d2 f2 {; H4 M, ?, e3 X9 l4 y0 O - /** Initialize RTC Only
4 }$ Z+ G. m4 M) w5 c - */
, A, ]& E' y4 P' A* J- V* ~ - hrtc.Instance = RTC;
t3 E& j0 o8 I _5 k - hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
" Y9 A( H: u3 G" P0 R/ t - hrtc.Init.AsynchPrediv = 127;: s% G6 f% t3 F& n
- hrtc.Init.SynchPrediv = 255;
' O- O5 e; b5 R+ x/ B - hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;2 x( r0 [& Y3 C7 v) ]
- hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;7 {% ? ]; Z3 h: l# Y
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;6 l: _8 J, y. ~* [
- hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;& C- t+ b- E- r
- if (HAL_RTC_Init(&hrtc) != HAL_OK)! ?; L& o) j7 V
- {! F+ P# P8 M2 u3 L! T1 H
- Error_Handler();% k9 w5 ?8 r; y, z* U4 J+ h1 z* I8 ~
- }+ G+ ?, u% @# i: Y) N& Z
- /* USER CODE BEGIN RTC_Init 2 */! y- D, Y9 `2 z# H' A. U2 C
- ) T4 n) [4 C, W* _+ J- A
- /* USER CODE END RTC_Init 2 */
& m# i. n+ X8 Z+ \ - * G Q* b% G3 s
- }
复制代码
5 F$ X1 f7 P# k9 M
/ {' _9 Y, {% T/ {* O可以看到outline里面有很多我们需要的函数,那么自己扩展就可以使用了
1 J( i, e2 `! {( a, |
5 m# j6 U$ l7 ^- \% Y3 R0 V4 R# ?* o& P$ o
This function configures the hardware resources used in this example - void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)5 O9 I7 B4 \+ ~
- {5 V% _! w5 F/ L g, I/ q& O
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
# f8 j+ y# Z! |/ p - if(hrtc->Instance==RTC)
; Q: g+ t: w I" _4 Q9 d9 R) d - {6 G5 x* V% @2 D4 b2 ?5 |
- /* USER CODE BEGIN RTC_MspInit 0 */
. M7 D& R, o' T3 p; ? y+ ~ - ; U" P M. y" J: W
- /* USER CODE END RTC_MspInit 0 */
6 J* S6 q' j3 t' `- Q - /** Initializes the peripherals clock. \3 K3 P: I: _# s; v. a
- */
1 a( i ?- u& ], l - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;' Q8 N, k) ~- E6 r8 O! S6 Y
- PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
5 s/ T" F' k+ x7 \* ^4 m - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)) a* [4 L8 O* ^0 F) L* |4 c
- {- Y7 k! \/ s2 E7 i) m" z1 A
- Error_Handler(); G5 T/ P' R1 l0 {
- }4 W8 O( X# L# A) y" W8 ]2 {% K/ T
- . [$ I$ T# A b5 P: @# \* q
- /* Peripheral clock enable */
) K9 C$ \- K" d4 Z( l8 ? - __HAL_RCC_RTC_ENABLE();
9 {6 D9 ?$ t+ M6 _ - /* USER CODE BEGIN RTC_MspInit 1 */$ Z2 u1 l2 s- E% x7 Z
: G' _. E/ g; C) y" W" C- /* USER CODE END RTC_MspInit 1 */3 P$ l! o- \; k$ |! q4 J
- }/ ~5 c3 w2 Y% K" v, E
- O& U# g6 i" i. d' t$ o- }
复制代码 最后,可以按需定制自己的实现方式,RTC是特别实用的一个模块了。
5 x# L5 {0 Z% b0 P+ }% m/ `, `. {( t9 k: k7 D! b* D) t
7 {6 P0 ?9 ?# P- Q6 a# Z
2 t- T- E( \% d$ j8 _4 A9 J# n4 i作者:李肖遥
0 [( X8 j$ A* j4 F! @! E |