STM32H7时钟配置问题
( R0 Y0 G, b7 s) F设备:stm32h735VGxxx1 w+ c# J! o- \# U1 W" z T: z
" t! Q: G. R! d/ n& u问题:STM32时钟配置不正确,一直没法启动。
5 R O7 y+ ^4 S. y; M0 Y* ?6 ^" r
# g8 n. G% C: Y* c解决:原因是配置时钟的一些参数超出的范围,所以配置导致不成功。
4 a1 ]/ O1 [8 E' E- E4 T8 m. W9 x- `, f8 b5 ^
下面是H735的时钟的一些解释,其中 Fvco 是有范围的,这边从文档上面查到,FVCO的最大配置值为836M,所以配置的时候一定要注意。/ w; d/ o+ V$ y( m3 f( \2 J2 G$ @
并且plln, pllm,pllp,pllq,这些都是有范围限制的,如果配置错误,那么芯片将不会正常运行8 O4 {1 _$ }9 q" U5 z( O1 R; u
6 Z% k9 F6 B* Y3 E- /*' O/ Z( u; O, c0 Q, G* W: a/ ]
- * 时钟设置函数- x& t+ H8 ^( B) ]
- * Fvco: VCO 频率
( @( O, [3 J& S# V9 _ - * Fsys: 系统时钟频率,也是 PLL1 的 p 分频输出时钟频率
& _& f8 `, H, {5 N, j - * Fq: PLL1 的 q 分频输出时钟频率; L% c" Z7 S' j) M% D
- * Fs: PLL 输入时钟频率,可以是 HSI,CSI,HSE 等. 0 u q3 x# h% z& g; h+ `0 p4 U& W
- * Fvco = Fs * (plln/pllm) = (Fs/DIVM)*DIVN;, ^5 [. s5 o* L5 B8 x4 x0 z
- * Fsys = Fvco/pllp = Fs * (plln/(pllm * pllp));0 A1 a' m( q& v0 c" [4 Y0 v7 K% F
- * Fq = Fvco/pllq = Fs * (plln/(pllm * pllq));
& W' K ~# R0 [+ B - *
7 n( E; p8 ]. b+ z9 Y! h% Z) f1 K - *
' ^+ \" N4 d3 t J4 G - * plln: PLL1 倍频系数(PLL 倍频),取值范围:4~512.* I, ~8 e! h# z
- * pllm: PLL1 预分频系数(进 PLL 之前的分频),取值范围:2~56.
6 f; G/ J. r% @. j9 Q. t2 r - * pllp: PLL1 的 p 分频系数(PLL 之后的分频),分频后作为系统时钟,取值范围:2~1288 S" I) Y" M; j6 W7 ^
- * pllq: PLL1 的 q 分频系数(PLL 之后的分频),取值范围:1~128.
' w3 y/ z/ b0 \5 x1 ` - * CPU 频率(rcc_c_ck) = sys_d1cpre_ck = 400Mhz
6 {0 x1 e7 V2 e8 M - * rcc_aclk = rcc_hclk3 = 200Mhz
- H7 d: ~/ u) r8 ?! i* [ - * AHB1/2/3/4(rcc_hclk1/2/3/4) = 200Mhz 3 |. _5 K& o2 C, l( ^
- * APB1/2/3/4(rcc_pclk1/2/3/4) = 100Mhz " `6 c4 W- r2 K G" c
- * FMC 时钟频率 =pll2_r_ck=((25/25) * 512/2) = 256Mhz% x7 G. H& |" b8 p# F; y
- *
& X% d# e/ R, B( M) N% @ - * Example:
+ i* u* N( V. { a, L% q# L1 u% e - * 外部晶振为 25M 的时候,推荐值:plln = 160, pllm = 5, pllp = 2, pllq = 4.6 H# h& ?# A! r6 u/ R, `
- * 得到:Fvco = 25 * (160/5) = 800Mhz/ s" p, `0 z3 p) @9 d
- * Fsys = 800/2 = 400Mhz
& D8 [) X( x' d* R; b6 A - * Fq = 800/4 = 200Mhz- k" j/ T( H2 f9 r/ p2 p5 X1 F% G
- */$ r' H2 w# J6 w
- 6 D* V) }& v3 E8 d1 E
- #define PLL_N 160
- L+ T. v: E" {+ u - #define PLL_M 5
. `& f+ k7 ^# U' r" O- I+ [' \$ } - #define PLL_P 2
0 O2 o( U% h2 k* U - #define PLL_Q 4) |8 T! |- ?9 k; X9 ^5 [
7 T# a7 }/ Q9 s6 U- // 时钟设置函数
6 l" C/ i+ V5 G: u) |5 v - static void SystemClock_Config(void)$ T0 ^/ [( k$ a. R$ b
- {
; `+ C7 }6 ]( @# q& ~/ a6 S: | - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
( J& K: P7 o0 b; e. h# @) ? - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; x5 X9 `( p- `" O1 B
- HAL_StatusTypeDef ret = HAL_OK;
- r3 |: J% g: a! |& l - 6 \) D2 T" T. t
- /*!< Supply configuration update enable */5 @: D& R- R$ D3 N/ C* z8 X
- HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);& G5 _& Z# I8 ?" O0 l& a. o
- ! z! h/ F/ w* W& Q& ~* s2 G" z
- /* The voltage scaling allows optimizing the power consumption when the device is u$ q/ d* G. A& F v- Z& p
- clocked below the maximum system frequency, to update the voltage scaling value& @% L% i" R( r3 M. [/ ]
- regarding system frequency refer to product datasheet. */
% |+ Y! R* h5 T N, u+ a0 a9 w% W O - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);" ~1 ^1 X& a% F5 e0 ~0 D* L
7 i! d: i. `/ K' X @. q- while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}0 x. w& j# e3 `" U- u) w
- c- R' H) q @/ c; Y8 F2 ?
- /* Enable HSE Oscillator and activate PLL with HSE as source */+ P L# a: T9 J& l- l! H
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
/ `/ T& _% k0 q! E; T% G - RCC_OscInitStruct.HSEState = RCC_HSE_ON;9 [3 i+ N" {) f! Y- M3 w
- RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
) @* E9 v- b4 V' U - RCC_OscInitStruct.CSIState = RCC_CSI_OFF;8 g0 w0 N0 [- f5 F, d( o* ]
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;* a/ Z, X' U- f2 W
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
/ F# ?: e0 D& L; t& O6 {4 k
1 [9 ^& o e0 E3 s" v- RCC_OscInitStruct.PLL.PLLM = PLL_M;
: V$ V. w; V& T, | - RCC_OscInitStruct.PLL.PLLN = PLL_N;# a/ a6 k2 z$ s) l
- RCC_OscInitStruct.PLL.PLLFRACN = 0;; l8 C+ Z1 G: X5 h& K5 W6 r; I
- RCC_OscInitStruct.PLL.PLLP = PLL_P;
3 S' _$ S6 M1 P1 j2 T4 o - RCC_OscInitStruct.PLL.PLLR = 2;
" G; a# e ?$ h2 d4 y - RCC_OscInitStruct.PLL.PLLQ = PLL_Q;" n, t: z c# u+ d. `% `+ Q. d( v
0 y" ]& {1 ` k. g- RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
# V4 f5 `& f+ m3 u+ D/ B - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;9 Z, i/ W- ^/ f# b; y
- ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);) i- x& C# U& w+ H% V0 a
- if(ret != HAL_OK)
0 x# b5 D0 z# _. W - {/ X* I: U* W$ `8 n! \* Q4 f+ n
- while(1) {};
4 U# b! t7 ]# O4 O: x - }
$ Y9 n2 }9 l$ N* ` a - . n s2 x9 x4 P6 Y, v( k- n
- /* Select PLL as system clock source and configure bus clocks dividers */8 \ k4 B: M' Q/ j
- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
; e8 @' x, [" a- Q1 ^ - RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
* x! P5 T; p8 R( @$ T' K
$ `7 [& E+ M, o- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;2 [3 u4 f! Z( {; }9 I1 [ G0 C
- RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;& x( m3 e, ]( e2 t: C7 J3 D
- RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
& {9 _, F6 {6 M' p - RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;' U( `& x: N8 c2 Z; \
- RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
: o3 S6 ^5 o% N% [1 b# [* m - RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
4 Y o9 I& N a" g - RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
8 L9 z$ j- a% O y - ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);2 _7 A" O, g1 r$ t( C$ O+ r a, T
- if(ret != HAL_OK)+ q& X) {" r2 N1 t$ J9 c
- {
j! q3 \5 L# h* Q+ H' G) d# O$ E9 L - while(1) {};
& ^7 ~' A! n7 B - }# r( u; k6 T. M, c5 v% w% D
- ! y* ~! [/ }5 O, E$ y! E; t
- }
+ v6 n( {$ z8 ^
复制代码
: L5 L/ ?4 i4 I% j) t% E
) O$ [2 x4 x B* s" Y9 a- L |