你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32H7时钟树RCC分析--- HAL库配置(二)

[复制链接]
STMCU小助手 发布时间:2022-3-23 14:00
启动流程5 P4 X: Q$ {5 @& M4 }) F7 b
H7的启动流程我们再说一下:% h' }0 |* q8 x4 j) Q
! M8 H0 }& }6 P/ f6 }* b
系统上电复位,进入启动文件 startup_stm32h743xx.s,在这个文件里面执行复位中断服务程序。
' N) j7 c$ q7 l' J* n; K在复位中断服务程序里面执行函数 SystemInit,此函数在文件 system_stm32h7xx.c 里面。( B, B( M6 F" a- D
之后是调用启动文件__main,最终进入到 main函数
! e# }0 g, V0 G4 b7 j进入到 main 函数就可以开始用户应用程序编程了。在程序运行之前需要:6 N0 `# H5 }4 f- L" O5 N. B
MPU 初始化,需要用到库文件 stm32h7xx_hal_cortex.c 和 stm32h7xx_hal_cortex.h。
* L2 z# i+ B. [0 p+ `) l1 ~Cache 初始化,需要用到 core_cm7.h 文件。  l/ X" k! x4 M+ Y
HAL 库初始化函数 HAL_Init,对Systick滴答定时器初始化,需要用到文件 stm32h7xx_hal.c。
! P/ e, w. v0 T" x! g1 y系统时钟初始化,需要用到库文件 stm32h7xx_hal_rcc.c5 U6 ]; R5 j* S3 z5 A# q
- f) y  j, P6 r3 r9 p1 ~  Z2 i
要注意的是,Hal库的SystemInit函数对于时钟只做了:复位 RCC 时钟配置为默认复位值(默认开启 HSI) 并没有做其他的配置,所以时钟初始化还要用户自己配置。
' Z4 Y7 ^  v3 d/ x/ H
; h+ _; H4 m2 V+ y我们今天关心的就是最后一步的系统时钟初始化
- }* X" S) I& Y7 w% \$ b- L& v8 K* n" o4 ], x9 \# @
上面的四步,在执行完HAL_Init之后,系统还在用内部高速时钟 HSI,对于 H7 来说,HSI 主频是 64MHz; ]; p, x6 ?! `4 o% k
) M/ {' A& K9 q; O
修改时钟配置

0 }  d+ F* U, X2 ]那么我们来看下如何修改时钟的配置:. r8 D1 L  c  Y- V$ ]6 Z$ U

/ {1 B! H6 q& _4 Y+ k+ y% }9 [  r第 1 步:在 stm32h7xx_hal_conf.h 文件配置 HSE_VALUE. g+ p: }0 t+ ?+ W; p# C
配置的大小要跟板子的实际晶振大小匹配。; P6 Z8 ~% w7 I+ W& M' |6 d
+ V7 u3 g& N* A" H- G  R
我使用的外部晶振是25Mhz的 所以配置为25000000
  1. #if !defined (HSE_VALUE)
    # t3 u7 Z1 Q' N/ I9 e# J
  2. #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
    : H; o: o' i9 l
  3. #endif /* HSE_VALUE */
复制代码

+ Q4 X8 _2 }2 r0 p7 C, v第 2 步:然后我们初始化时钟,最主要的就是两个结构体参数和两个函数:
  1. RCC_ClkInitTypeDef RCC_ClkInitStruct;  // 配置时钟源相关参数8 k% I" n& O. A+ r
  2. RCC_OscInitTypeDef RCC_OscInitStruct;  //配置系统时钟源及各个外设分频系数
复制代码
  1. HAL_RCC_OscConfig()  //配置时钟源相关参数
    ! v* Y5 F# w2 [. `- p
  2. HAL_RCC_ClockConfig() //配置系统时钟源及各个外设分频系数
    # x% }! I) n6 V! T) M
复制代码
' _; K; C4 V  ]' ^, |
HAL_RCC_OscConfig()
" A6 u: _$ U, j5 Z( `, r: x! {
HAL_RCC_OscConfig() , 该 函 数 在 HAL 库 关 键 头 文 件stm32h7xx_hal_rcc.h 中声明,在文件 stm32h7xx_hal_rcc.c 中定义。首先我们来看看该函数声明:( `' |2 b" x# p  U
: K) I. W, A( s
  1. __weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
复制代码
% ]/ I: D, p0 x3 R* p% S3 K8 K* Q
只有一个RCC_OscInitTypeDef 结构体参数,我们来看下这个结构体:
8 l9 \% b$ |, R% J
7 `% W- H, Z0 ]0 {. \
  1. typedef struct+ i& ^0 L  @9 |5 u1 _( [8 s
  2. {
    ! [" I' n, a! ~  r& G7 x
  3. uint32_t OscillatorType; //需要选择配置的振荡器类型
    # k# u- w2 g$ a" z
  4. uint32_t HSEState; //HSE 状态
    - _" h( v9 }% A& n2 B
  5. uint32_t LSEState; //LSE 状态
    + }+ ~. a$ c4 Z! u
  6. uint32_t HSIState; //HIS 状态
    6 Q* i9 G0 b$ l3 _& w. U
  7. uint32_t HSICalibrationValue; //HIS 校准值
    # Y( l8 @5 I1 l; y% d% q  @
  8. uint32_t LSIState; //LSI 状态 / _, A. d% l/ V5 w- X* W9 \
  9. uint32_t HSI48State //HSI48 的状态/ D' z* B7 z- x  k9 I( \9 H
  10. uint32_t CSIState; //CSI 状态
    * D) d2 @0 F# e' L2 c. B# O
  11. uint32_t CSICalibrationValue; //CSI 校准值
    9 l4 {, N% y7 S$ p4 N% Q
  12. RCC_PLLInitTypeDef PLL; //PLL 配置
    4 M/ S. ^2 R0 n% c$ Y
  13. }RCC_OscInitTypeDef;
复制代码

9 V* N! w3 Y) G# b! C7 D第一个就是选择振荡器的类型,比如我们要开启 HSE,那么我们会设置 OscillatorType 的值为 RCC_OSCILLATORTYPE_HSE,然后设置 HSEState 的值为 RCC_HSE_ON 开启 HSE。对于其他时钟源 HSI,LSI 和 LSE,配置方法类似4 ]( \! W! B. X

4 d5 @- }( I7 {9 F# U1 b7 J最后有一个 RCC_PLLInitTypeDef PLL; //PLL 配置
3 U3 c( f0 j2 `: a
2 `: ~; M  V+ B6 H' b  u这个就是配置锁相环了,结构体参数如下; b8 o; G' t" s& D
3 r  Z9 v, A. l& |6 j- a
  1. typedef struct
    6 t3 P/ ~& V% }( f/ u
  2. {
    0 v" O6 }; A! ?: K' a
  3. uint32_t PLLState; //PLL 状态  E3 x" B0 p9 [( i- b+ k/ h
  4. uint32_t PLLSource; //PLL 时钟源
    ) H* x0 U; P3 s+ F( v' y
  5. uint32_t PLLM; //PLL 分频系数 M1 `9 y) q9 V0 J* ?1 T* e
  6. uint32_t PLLN; //PLL 倍频系数 N
    ( ^: C. I- ]8 `
  7. uint32_t PLLP; //PLL 分频系数 P3 k* _( ?. l  h( K4 j: A
  8. uint32_t PLLQ; //PLL 分频系数 Q! G% O5 K/ {9 }7 \
  9. uint32_t PLLR; //PLL 分频系数 R7 I6 i3 y9 ?5 j  U, G
  10. uint32_t PLLRGE; //PLL1 时钟输入范围8 L4 D. F" b' v/ n
  11. uint32_t PLLVCOSEL; //PLL1 时钟输出范围
    ( k) D) S8 _  F/ V
  12. uint32_t PLLFRACN; //PLL1 VCO 乘数因子的小数部分; @2 ?* E3 Q+ [2 k# C& L4 F3 N
  13. }RCC_PLLInitTypeDef;
复制代码
( Y# B- E: G, Q3 S& D7 R, B9 m8 b
这里的分频系数,全部都是PLL锁相环内部控制,我们要做的就是明白具体的公式就行
/ E4 ~$ W. ]* o, ]) Z% `5 r7 GFvco:VCO频率
* o' C7 B+ A" k# `7 u2 E% UFsys:系统时钟频率,也是PLL1的p分频输出时钟频率 pll1_p_ck$ y; l# B8 s2 s1 b
FpllqLL1的q分频输出时钟频率 pll1_q_ck) J6 i3 w4 [4 s& H
ref1_ck: PLL输入时钟频率,可以是HSI,CSI,HSE等.

6 j* Q; ~) `$ a: w3 ~+ [/ U+ n; H) k1 Z9 m  S
pllnLL1倍频系数(PLL倍频),取值范围:4~512.
0 {! n5 P$ b$ B# M/ spllmLL1预分频系数(**LL之前的分频),取值范围:2~63.( `2 @! I# g' f$ b9 A+ S! ]
pllpLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)
, m' B) k  B5 _# b9 mpllqLL1的q分频系数(PLL之后的分频),取值范围:1~128.: u: N2 Q6 _5 P* N# o+ h. L

+ D7 d! I2 M5 F  L% J) S FOXV5CS$TF$EC}LD$F6K4S2.png
% u3 o0 M$ A: f/ h
5 J( b+ F0 E, Z0 h  a0 c
  1. VCO频率: Fvco= ref1_ck*(plln/pllm);. [1 n" m# @! N, e" f) N' y/ h
  2. pll1_p_ck频率: Fsys=Fvco/pllp= ref1_ck*(plln/(pllm*pllp));
      x3 Y& o: Q- W
  3. pll1_q_ck频率: Fpllq=Fvco/pllq= ref1_ck*(plln/(pllm*pllq));
复制代码

, j8 h; d2 K  J+ P {_{)ZU9EI]$R3}8ORBES7_B.png
  b' Y& x! Z. P, \/ p; |
2 K3 x" H  N4 t0 P7 {6 a9 Y. N9 ^具体的公式如下,上一篇也有讲解
* R, J; E- d/ F+ w& u) E
7 Z! o  Q. o& W" Y YO4U@_534{J@C}0L]}KMDI6.png
, T3 L: `4 V, J' ^" ~1 B" b/ ~( [# o
HAL_RCC_ClockConfig()
' G2 u2 @/ p! I2 G. ^接下来我们就要看 HAL_RCC_ClockConfig()函数,声明如下:* {: s. C) K( Y( u$ ]- ]
2 g1 \) H" i1 o+ g1 p# c
  1. HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct,
    & C! A: o5 H- y* ]. ^/ `6 V/ q4 p
  2. uint32_t FLatency);
复制代码

% c" M8 U$ P$ N一共有两个参数:第一个入口参数 RCC_ClkInitStruct 是结构体 RCC_ClkInitTypeDef6 X; I, i% D, g! S5 e, l
指针类型,用来设置 SYSCLK 时钟源以及 SYSCLK、AHB,APB1、APB2、APB3 和 APB4 的分  t4 e7 u* X" N6 |% R
频系数。第二个入口参数 FLatency 用来设置 FLASH 延迟
5 L0 g5 g0 r8 ]/ F% Z9 c2 Q* j2 L- x& u9 ]( A. t+ Q. ^
我们开看下RCC_ClkInitTypeDef 具体位置在stm32h7xx_hal_rcc.h 中声明- g. e4 Z# o0 c* A- o; |( V& N
  l& i/ W0 u6 s
  1. typedef struct  _  a. J, C7 M* I8 I  i) V
  2. {
    : b+ m  Q$ I& B# s
  3.   uint32_t ClockType;             /*!< 要配置的时钟。
    4 u: [% r* p* j* |' j% z/ F$ K
  4.                               该参数可以是@ref RCC_System_Clock_Type 的值     */
    ! M6 w2 y  T( E8 l6 i- a* Z

  5. 6 R, o9 F  M6 B7 r4 y  W" J
  6.   uint32_t SYSCLKSource;          /*!< 用作系统时钟的时钟源(SYSCLKS)*/
    8 y% w# U* M5 M
  7. 4 `0 h& ~# o+ c; R, a- P
  8.   uint32_t SYSCLKDivider;         /*!< 系统时钟分频    */
    - B- h! K2 W, K2 M! n" z) k2 C

  9. - \! L; c. X8 ^' s8 C; d& o
  10.   uint32_t AHBCLKDivider;         /*!< AHB分频 */* b8 ?5 B. r: A4 b
  11. 8 }9 W' j' O8 v( V7 A0 g* u
  12.   uint32_t APB3CLKDivider;        /*!APB3分频*/# B- d# E$ z# V, P% l/ a
  13. 4 x, @3 s7 v3 N6 e# ?, g2 y0 N6 k
  14.   uint32_t APB1CLKDivider;        /*!APB1分频*/
    7 i1 E5 I! g' p/ \0 t) L$ [3 Q! X$ p
  15.   uint32_t APB2CLKDivider;        /*!APB2分频*/" n- o4 L. F. ^# Z
  16.   uint32_t APB4CLKDivider;      /*!APB4分频*/: O$ {: i( {+ I3 a( s: l
  17. }RCC_ClkInitTypeDef;
      V- Y& f; V( g; O$ Z
复制代码

! `# k5 e$ A4 R第一个参数 ClockType 配置说明我们要配置的是 SYSCLK,HCLK、D1PCLK1(PCLK3)、
2 E' [; Q1 `4 A) d& n5 zPCLK1、PCLK2 和 D3PCLK1(PCLK4)六个时钟。
# }( p+ W. i% n  K* Q第二个参数 SYSCLKSource 配置选择系统时钟源为 PLL。
8 ?* L) }* V& {第三个参数 SYSCLKDivider 配置 SYSCLK 分频系数
% {$ b+ E& R# i0 x第四个参数 AHBCLKDivider 配置 AHB 分频系数
6 O9 c1 \# d+ _7 d) A第五个参数 APB1CLKDivider 配置 APB1 分频系数# @  D, P1 s" C: P! v
第六个参数 APB2CLKDivider 配置 APB2 分频系数
4 W1 d- s& W* b2 I% q9 I: I第七个参数 APB3CLKDivider 配置 APB3 分频系数) J$ z5 A  h7 a9 K
第八个参数 APB4CLKDivider 配置 APB4 分频系数1 w* v& v- J0 [' c# b

* Z  r: L, A, i+ J' ]6 S) L这个在下面有详细的介绍
# A% X3 X8 G3 y3 d
& A. e+ |* C: F6 v6 F2 Y然后我们看第二个参数:FLatency 用来设置 FLASH 延迟和调压器VOS9 w3 ?7 _3 m9 c* L

' b! Q. s: C  A4 O, @$ D那就需要知道Flash 读操作9 v  r$ |% f) W8 H2 G' ]
' A! [, u2 B# a9 S  \) K* v7 _8 J
Flash 读操作 是每次读取完Flash数据,需要延时一定时间,确保之后的数据传输正常
! u6 C: M9 Y6 t9 n: C: C  r/ v' E
VOS:在STM32H7中,系统Flash的受到调压器输出电压级别选择(VOS)的影响(在电源控制寄存器中)
* Y" |6 U- p, }" N9 O. u4 f6 K0 E& f2 q
为了得到最高的FLASH读取速度,我们需要设置VOS级别为1 然后等待数设置为4 就可以得到最高的Flash读取速度,ST 官方例程使用的就是 4 个 等待状态数
* w" B  [- k9 q- G2 K- ~, S- _5 l9 ^6 N+ |' r& ]6 u/ O
`~PBE4ZQVW`UAVP%~(Q[@8X.png
- @8 ^: B5 r* a* `( E8 }5 h# [7 S( ?* u' p/ m
STM32H7xx参考手册 112页# {1 k" Z, ?' [% n1 ]' l8 J# B

7 P4 w% H; [* U8 O最终代码如下:
' z7 H: ]1 J* v, w
  |( I3 V9 u# c$ U2 r4 g! i都做了注释
! ]; }6 W6 t8 S, g6 ?! v# o
5 `- w' b" ?( b% g) S/ x
  1. / Z1 U( A7 w5 a' H# v
  2. + ^! q1 |8 z! i$ p3 T9 t" n( i
  3. /*
    : ]% |3 y: z7 X) l
  4. *********************************************************************************************************
    0 Y  t3 Y$ i5 V8 v8 ^# ~
  5. *        函 数 名: SystemClock_Config
    3 \/ E* l9 @  U3 u3 ]6 I# W
  6. *        功能说明: 初始化系统时钟
    - N( M$ Q/ ~  |* f4 F7 x$ K
  7. *                    System Clock source            = PLL (HSE)- @9 b) D6 ]  X9 ~
  8. *                    SYSCLK(Hz)                     = 400000000 (CPU Clock)
    ) ^! e7 W5 g' w
  9. *                   HCLK(Hz)                       = 200000000 (AXI and AHBs Clock)
    0 @; @/ d: \- d% B- ~6 M
  10. *                    AHB Prescaler                  = 2$ T- Z! s) O2 n( V! d+ g" T
  11. *                    D1 APB3 Prescaler              = 2 (APB3 Clock  100MHz)" K  @' ]# y% w* ?$ P: S
  12. *                    D2 APB1 Prescaler              = 2 (APB1 Clock  100MHz)/ H0 R: F+ K( K3 F; o
  13. *                    D2 APB2 Prescaler              = 2 (APB2 Clock  100MHz)* ]3 m+ R  q4 }) m
  14. *                    D3 APB4 Prescaler              = 2 (APB4 Clock  100MHz)6 b  g" R# r' g/ d8 b9 ]
  15. *                    HSE Frequency(Hz)              = 25000000; V2 \4 Q" R( E- b
  16. *                    VDD(V)                         = 3.3
    ) }) ]$ n, [& q: \0 V
  17. *                    Flash Latency(WS)              = 4- f' w, f( J2 D1 m6 P
  18. *        形    参:
    * C2 A) k) ^( c/ p& k3 c
  19. *           plln:PLL1倍频系数(PLL倍频),取值范围:4~512.
    3 _! Z9 q+ o/ Z5 {( B- ^1 v: l
  20. *                        pllm:PLL1预分频系数(**LL之前的分频),取值范围:2~63./ `" h' @6 T! H
  21. *                        pllp:PLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)
    : U) ~. V1 _: c3 ?( W, |( U
  22. *                        pllq:PLL1的q分频系数(PLL之后的分频),取值范围:1~128.* w. V9 h4 x+ C9 c" \# m' b  Q
  23. *
    + j7 ^% r5 n& Z  W: Z" Z7 @
  24. *0 |2 k: N2 F; H2 M$ g4 ?, W3 X
  25. *            Fvco:VCO频率0 \, ?% {' n) B& s/ l  T
  26. *            Fsys:系统时钟频率,也是PLL1的p分频输出时钟频率 pll1_p_ck( K1 b: g, m& ]# s5 e
  27. *            Fpllq:PLL1的q分频输出时钟频率  pll1_q_ck( I( u* [5 v" w. A  q0 P" [! i  N. h, `
  28. *            ref1_ck: PLL输入时钟频率,可以是HSI,CSI,HSE等.
    % l5 U2 a* C) D; p
  29. *
    8 ]* u5 p8 w# C8 \
  30. *0 S- L: X$ w7 w; S7 ?
  31. *            plln:PLL1倍频系数(PLL倍频),取值范围:4~512.+ [- v/ F" e+ n9 o& C, ]; v2 N
  32. *                         pllm:PLL1预分频系数(**LL之前的分频),取值范围:2~63.# I$ j2 k; y0 x8 l( H9 R% R
  33. *                     pllp:PLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)2 H7 j9 v  u% X0 g; Y" c" H' R% m
  34. *                         pllq:PLL1的q分频系数(PLL之后的分频),取值范围:1~128.9 Y6 j/ J: T6 H3 @- z
  35. *
    - V7 U& K% W8 D
  36. *
    # w4 D4 G6 J) L$ h' `. {& W
  37. *+ e# E( r8 j7 \
  38. *                         VCO频率: Fvco= ref1_ck*(plln/pllm);
    7 a7 w# |0 W# N% M9 P+ v
  39. *                         pll1_p_ck频率: Fsys=Fvco/pllp= ref1_ck*(plln/(pllm*pllp));6 ^$ r* W- i% L+ _' Q+ R, `7 U
  40. *                         pll1_q_ck频率: Fpllq=Fvco/pllq= ref1_ck*(plln/(pllm*pllq));
    * U5 V8 O6 P- g; {. U
  41. *
    ' ~( Z4 i2 m3 w8 k" m1 z
  42. *                        CPU频率(rcc_c_ck)=pll1_p_ck频率=400Mhz ) ~* y& K% e8 F2 w. d. h
  43. *                        rcc_aclk=rcc_hclk3=200Mhz
    + ~2 B5 M$ W$ |0 q- j
  44. *                        AHB1/2/3/4(rcc_hclk1/2/3/4)=200Mhz  5 H# T& ]) F1 k4 g' y1 n  F
  45. *                        APB1/2/3/4(rcc_pclk1/2/3/4)=100Mhz  & `. `2 X% j8 @% Y7 p1 C" Q6 k
  46. *                        FMC时钟频率=pll2_r_ck=((25/25)*512/2)=256Mhz
    ) v8 Q# R& y. y% n' {- m% d' F! l
  47. *& M) b) e: n4 Y9 T- N% Y
  48. *- E& O5 y, F( y! h/ a. u
  49. *          外部晶振为25M的时候,推荐值:plln=160,pllm=5,pllp=2,pllq=2.3 {" m9 o8 E2 ~' |6 @
  50. *          得到:Fvco=25*(160/5)=800Mhz8 n/ D. Q+ o& P) I) x$ Q
  51. *          CPU频率Fsys= pll1_p_ck频率=800/2=400Mhz- I& I# k/ }7 J$ I4 C  a. ^" `
  52. *          pll1_q_ck频率=800/2=400Mhz: w4 n* e' w( ?3 @
  53. *        返 回 值: 无! l# ^7 J( r  |8 E0 o

  54. 2 Q7 O. O4 L1 {0 P! o: m5 z
  55. *********************************************************************************************************
    - p1 `# ~0 s6 s5 G  A& {
  56. */
    9 }0 @0 ^0 z9 }
  57. void SystemClock_Config(u32 plln,u32 pllm,u32 pllp,u32 pllq)9 S  O) ]* w- X; M, C( O3 T- n
  58. {
    6 C* Z/ v0 J4 \: H5 F/ x* m
  59.         HAL_StatusTypeDef ret=HAL_OK;
    - G* N  G, K1 `* s) q
  60.         RCC_ClkInitTypeDef RCC_ClkInitStruct;
    # q2 \% k1 d+ g
  61.         RCC_OscInitTypeDef RCC_OscInitStruct;
    / ~0 v  W4 b) d, K9 p$ ~
  62.          /*使能供电配置更新 */
    8 n6 `3 z$ b. H# x" C
  63.         MODIFY_REG(PWR->CR3,PWR_CR3_SCUEN, 0);
    : a( @* l- q* B) \
  64.         
    2 P. e3 N% M' Y; Y; s7 M& m0 a
  65.         /* 5 Q0 P9 n6 t- C  W/ p5 M. x
  66.       1、芯片内部的LDO稳压器输出的电压范围,可选VOS1,VOS2和VOS3,不同范围对应不同的Flash读速度,! `. ?* H. k$ W0 M0 t
  67.          详情看参考手册的Table 12的表格。
    , i+ K  f4 o6 T+ O
  68.       2、这里选择使用VOS1,电压范围1.15V - 1.26V。
    1 Q; d: L' y7 ]* r1 w
  69.     */0 l' f2 V. A8 N+ b# x
  70.         __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);% P5 N( j5 `. V* p* }4 e0 Z9 c

  71. / d% o! Q! C- W1 t+ \! H0 f# ]
  72.         while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}
    1 A+ {; c- j* S* `( O
  73. 9 I0 }) u2 j( f9 b/ a+ H
  74.                 7 X' y- b" @! ?) `* @5 z
  75.                 /* 使能HSE,并选择HSE作为PLL时钟源 */; _9 T: l+ n( h' v/ K8 u
  76.         RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSE;. l8 ?  a( p  P) E
  77.         RCC_OscInitStruct.HSEState=RCC_HSE_ON;8 K) f5 [4 t- P- Q2 E6 [& g, g
  78.         RCC_OscInitStruct.HSIState=RCC_HSI_OFF;
    : e; ^  k" u) H" i3 N3 ~: t
  79.         RCC_OscInitStruct.CSIState=RCC_CSI_OFF;
    " l' q" v: l/ E& b* J5 A
  80.         RCC_OscInitStruct.PLL.PLLState=RCC_PLL_ON;  ?" Q5 C$ c9 e2 G6 s, |
  81.         RCC_OscInitStruct.PLL.PLLSource=RCC_PLLSOURCE_HSE;
    # ~# p  p, Z" b4 s8 W; T
  82. 2 L; {6 K0 o$ p9 {6 ^$ ^$ {
  83.         RCC_OscInitStruct.PLL.PLLN=plln;
    . e: s- h' f2 n. [& l, c- z, B
  84.         RCC_OscInitStruct.PLL.PLLM=pllm;8 C5 S+ b' S0 \' k: k# w
  85.         RCC_OscInitStruct.PLL.PLLP=pllp;
    % h) E) ~$ E. z" \( z
  86.         RCC_OscInitStruct.PLL.PLLQ=pllq;" P3 ?. K  O& A; H, L
  87. ( U) i) \5 y/ k8 U- C% r
  88.         RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
    ' X9 t2 w) N7 k5 f8 L4 N* q  F5 ~
  89.         RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;, G3 m. C; l# `  f
  90.         ret=HAL_RCC_OscConfig(&RCC_OscInitStruct);
    % _) @+ m- P: R) Y, a5 r
  91.         if(ret!=HAL_OK) while(1);$ |- C0 _$ Q/ q% V

  92. + j$ [' N  B0 y1 @  V
  93.                
    4 m  S; f( l4 ?# P8 c
  94.                 : B' O. O4 i7 E5 w3 p
  95.                 /* 1 [6 t8 M, A. f1 r. F, R
  96.        选择PLL的输出作为系统时钟% G& t% q5 K( U, H4 ]  N; D9 g
  97.        配置RCC_CLOCKTYPE_SYSCLK系统时钟
    4 N2 J0 `- a6 E3 w+ o
  98.        配置RCC_CLOCKTYPE_HCLK 时钟,对应AHB1,AHB2,AHB3和AHB4总线
    1 \% i1 o' c9 r! F/ ^
  99.        配置RCC_CLOCKTYPE_PCLK1时钟,对应APB1总线. `1 i6 w. `+ l* t
  100.        配置RCC_CLOCKTYPE_PCLK2时钟,对应APB2总线
    2 `" o" ]0 P" x2 o3 L& d! L1 V
  101.        配置RCC_CLOCKTYPE_D1PCLK1时钟,对应APB3总线; G1 Z" Y; C1 I& ?
  102.        配置RCC_CLOCKTYPE_D3PCLK1时钟,对应APB4总线     
    " y7 i% Q' A3 \* _- G7 P
  103.                 AHB 分频系数为 2,故其频率为HCLK=SYSCLK/2=200MHz。2 W: F% Z: g' `" O7 r3 T
  104.                 APB1 分频系数为 2,故其频率为 PCLK1=HCLK/2=100MHz。; n$ @1 x' h+ g: \, }/ h
  105.                 APB2分频系数为 2,故其频率为 PCLK2=HCLK/2=200/2=100MHz,
    # |5 g8 y6 R0 F5 S" K, l& k( n
  106.                 APB3 分频系数为 2,故其频率PCLK3=HCLK/2=200/2=100MHz,9 E0 \8 y0 T* L5 Z
  107.                 APB4 的分频系数为 2,故其频率 PLCK4=HCLK/2=200/2=100MHz
    6 u! d! ]' `& c, E
  108.     */
    : J$ G/ P& r9 U7 {4 ~
  109.                
    3 ~/ I8 a: [3 J3 Z+ Q
  110.         RCC_ClkInitStruct.ClockType=(RCC_CLOCKTYPE_SYSCLK|\
    " y* @' C& K9 u9 U; |  ]
  111.                                 RCC_CLOCKTYPE_HCLK |\
    ( e2 s* C% Q; J2 r! \# \+ ~, K# G
  112.                                 RCC_CLOCKTYPE_D1PCLK1 |\0 r: o0 z* R$ Z& z% x' t
  113.                                 RCC_CLOCKTYPE_PCLK1 |\' {8 ]# g! H- M9 i3 g
  114.                                 RCC_CLOCKTYPE_PCLK2 |\
    1 A( f0 s$ I" g: c1 M
  115.                                 RCC_CLOCKTYPE_D3PCLK1);' E% a2 z$ A" [: D$ T8 H- B' ^

  116. 3 l/ I+ a0 [, Q  l$ H
  117.         RCC_ClkInitStruct.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;
    & F) n/ V/ V9 S; I2 y
  118.         RCC_ClkInitStruct.SYSCLKDivider=RCC_SYSCLK_DIV1;
    + o3 z/ F- n6 `/ b' d5 |0 |$ X
  119.         RCC_ClkInitStruct.AHBCLKDivider=RCC_HCLK_DIV2;. U2 f; z7 Z- N! x) d
  120.         RCC_ClkInitStruct.APB1CLKDivider=RCC_APB1_DIV2; , d7 c6 B4 L$ L7 D  Q8 B% K0 M
  121.         RCC_ClkInitStruct.APB2CLKDivider=RCC_APB2_DIV2;
    * X& S8 j; G$ S& {! S, N' h7 _, @
  122.         RCC_ClkInitStruct.APB3CLKDivider=RCC_APB3_DIV2;  
    - ?* p+ Y7 a& Q  N; i1 p  v
  123.         RCC_ClkInitStruct.APB4CLKDivider=RCC_APB4_DIV2;
    0 ~3 k' Q' x" s% }& e6 l; y) g
  124.         
    ! ~- Z' r( [+ F+ Q: ^! z
  125.         /* 此函数会更新SystemCoreClock,并重新配置HAL_InitTick */! E! J6 L/ b9 R- p& k7 C7 m
  126.         ret=HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
    - ~$ N1 _/ `6 F5 h4 ?
  127.         if(ret!=HAL_OK) while(1);
    + z5 R: B; s! R, J
  128. + m4 l9 f' u# B/ M
  129. $ u4 c, L0 ?7 ?+ D& _8 O

  130.   C! o( T5 [/ H% T
  131.    /*   使用IO的高速模式,要使能IO补偿,即调用下面三个函数
    ! H  w' ?, E( T* z
  132.       (1)使能CSI clock
    : V9 d6 z! {9 Z( X0 p
  133.       (2)使能SYSCFG clock
    - @5 z3 B$ M1 u$ F! i% ~1 s) Z
  134.       (3)使能I/O补偿单元, 设置SYSCFG_CCCSR寄存器的bit0& ?2 M, u2 j; x' t) Y
  135.     */
    1 z, }# Q; k  g1 ^$ |& G- d6 H5 @/ k
  136.         __HAL_RCC_CSI_ENABLE() ;
    6 G( A8 z$ w  m$ {; d# x- I  U
  137. $ J. [# F) {7 D: p5 F% U4 z" m2 ?' |3 q
  138.         __HAL_RCC_SYSCFG_CLK_ENABLE() ;
    , J1 m4 @( g" X9 q) c# _$ w- }
  139. $ _+ ?  g& i. |+ |
  140.         HAL_EnableCompensationCell();
    ! B& h" x, K% O# s2 R% a( }
  141. ! f7 E2 [9 a; P
  142. }' N- O0 k/ P% Y  y; P& l
复制代码
8 {; |8 B- L3 v. S! y

9 G5 j, h, b: e3 _主函数调用:
: l6 J0 p' j: L: j8 s
- ?* S2 H2 Y' w; M/ p; p
  1.         SystemClock_Config(160,5,2,4);            //设置时钟400Mhz
复制代码
1 `& l! y7 [( i; W1 j, P: @
3 j) f+ `. V6 i% _$ F: K; F

( }3 j9 ~; S9 C# K' z/ J
, m4 l: X; J% n" [
赞 收藏 评论0 发布时间:2022-3-23 14:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版