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

【经验分享】STM32F2XX之RCC配置

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:23
一、系统时钟配置
, z& N' G. v; R2 n$ t) D4 P! D+ h1 R1 |" J! L$ R" p1 m
STM32有多个时钟源,分别是HSI,HSE,LSE,LSI。3 E$ x6 p+ T3 N' W0 q

7 D! l- `. i  T- s* g$ UHSI振荡器时钟:3 f& m! ^" e& L! Z- `% y3 d( [

9 J9 |3 V0 z, k: g8 I9 h" h, @系统上电默认时钟,内部振荡器8MHZ,可以直接作为系统时钟或在2分频后作为PLL的输入。时钟频率精度较差。5 P3 i4 _$ ]7 B3 K* v) S
( a0 l3 L2 J2 \' f% ~  l! W
HSE振荡器时钟外部:- n/ n. i/ }2 \8 }8 `) C( r

4 q4 T, X6 i6 B8 s$ S提供非常精确的主时钟,STM32F1系列的板上为8MHZ,STM32F2系列的板上为25MHZ晶振。经过PLL倍频:作为系统时钟。  C, x" G# L1 v9 P
( Z  H, D; x" t- q6 Q
PLL时钟源输入可以是HSI时钟的二分之一,或者HSE时钟。
6 w2 s( i$ ?) x* w8 y. Z. i2 i9 L( d+ T0 z4 U4 j* M3 h
LSE时钟:
$ M  j$ c7 w. `5 c
0 J2 I$ ~2 }, ]3 e1 nLSE晶体是一个32.867k的低速外部晶体。提供实时时钟。一般专门用于RTC,等到RTC模块时再使用。/ c% B# b4 y0 H* ~6 i3 {
( I  z/ d/ q6 n2 B% I% d
LSI时钟(Internal内部):
  d  C1 ?: S/ V  o
" \+ P3 A  z+ B& ?) u5 ]LSI的RC担当一个低功耗时钟源的角色,它可以在停机和待机模式下保存运行。为独立看门狗和自动唤醒单元提供时钟。LSI时钟频率大约40KHZ。一般用于IWDGCLK。- H. a/ b, _: c' b

$ ?% v9 I  A3 {) {8 r8 G8 q通常的时钟选择为HSE配合PLL使其工作在72MHZ(STM32F1系列)或者120MHZ(STM32F2系列)。2 l; v2 |- Z, X2 K% r! Z

- b1 d' {) H2 K7 }* L9 K8 P& w
1336782557_3471.jpg

* U( f  k* ?2 m/ w4 r- h6 _$ T! n8 e+ z: N- y
STM32F1xx系列

$ M/ a, s! F" e" d- L% K
- k! b# ~# t$ A/ p
1336782592_5508.png

9 O1 n$ r9 z5 U  ?) Y
7 ~+ E6 b+ D% r/ J; s1 z( G+ s
STM32F2XX系列

- H  P9 c3 {; K1 q9 t9 x. C/ n4 z8 F7 \0 c- q5 E$ ~2 C3 l
RCC_DeInit()同SystemInit()的区别仅仅在于SystemInit()多一个SetSysClock()。SystemInit()包含了整个内部时钟到外部时钟的配置,但配置的频率不可调,如需调整频率,可以自己用RCC_DeInit()再配合其他操作进行。: I. e- R. |! W3 Y: k4 h

- }0 Z( _1 g. [; y- g" Y+ W$ Q配置时钟流程:

1 A% @' t+ J2 V0 C) m# a# v3 I3 t) P5 e5 p
1.将RCC寄存器重新设置为默认值         RCC_DeInit;
4 A- X% v" {' \4 [0 e- J  M- n2 [. h. j! W# x* x
2.打开外部高速时钟晶振HSE                 RCC_HSEConfig(RCC_HSE_ON);4 A. L2 e! G  y7 L
6 W! R& W/ l0 l. @# Z, `  Q
3.等待外部高速时钟晶振工作          HSEStartUpStatus =RCC_WaitForHSEStartUp();
, U; U6 H$ V- _; A/ h6 E& V  t; R% \: ~
4.设置AHB时钟                              RCC_HCLKConfig;0 |6 x7 l7 w( @8 D5 i  M0 K) c" H; x

% T8 A* J/ r' c! t0 p) a/ C2 X5.设置高速APB2时钟                     RCC_PCLK2Config;  `; f9 _3 j/ e4 v/ ~

/ a0 ^3 U2 F1 s* X: h* y7 z6.设置低速速APB1时钟                  RCC_PCLK1Config
2 d' @2 r6 T% L! f& E. A9 j/ _( Y5 x7 E
7.设置PLL                                       RCC_PLLConfig;
2 ^7 R5 `) d: F; s+ l- |0 b7 S. v% _
8.打开PLL                                       RCC_PLLCmd(ENABLE);
+ i' Y4 k& R7 S# l
; N( Y- B& @: G, W9.等待PLL工作                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
3 e6 t( {: U( a6 e$ p
& q+ Q' i1 E9 r10.设置系统时钟                              RCC_SYSCLKConfig;
- {7 N0 K+ t1 u$ X' ~, l% B
9 ?% B% M/ O! X0 k( N9 C) g. [11.判断是否PLL是系统时钟            while(RCC_GetSYSCLKSource() != 0x08);4 V' p" I5 q( r2 h& ], M+ o
) U' b! {; R% J
12.打开要使用的外设时钟
  1. RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd();. o5 A, N+ J! S) z0 ?& k0 a! i% b8 W
  2. - X2 J' g0 |3 Z* T
  3. /*******************************************************************************
    9 [4 o# x: i( r4 ~8 ~! d. B
  4. ( h$ A, s' K& s/ t2 v
  5. * Function Name : RCC_Configuration
    ( g' ~* \- N2 R0 j

  6. 4 W/ u7 k5 V8 P* b, }' |: m
  7. * Description   : Configures the different system clocks.% p7 z- P2 f# Y& u8 y

  8. $ W! P2 Y( M( L: _( j0 L9 W' ^9 K
  9. * Input         : None
    ! {4 }; e' |+ F1 C, F/ k0 r

  10. & n: q9 H0 _; J4 O6 m) P' \) z
  11. * Output        : None
    " a' J  L! S; O  T
  12. , i) m( {2 S6 y6 _
  13. * Return        : None, {& D2 }) n! v5 d9 I8 w* [$ w

  14. , y4 f- A, t  G( G5 m# c5 r3 @. ^' P! g
  15. *******************************************************************************/8 U! Y7 b, j4 }+ h

  16. : r. o% w$ u9 a
  17. void RCC_Configuration(void)
    $ F- f: I& {: h+ B' b

  18. 0 f! s3 a  I0 l; u" b
  19. {9 R9 \3 Z$ X; ~: W( J9 v

  20. 6 E9 Z- E# y1 J
  21.   /* RCC system reset(for debug purpose) *// j5 t3 C5 g3 w/ O4 O4 E

  22.   X) B! \& a' E$ |9 Y1 m# ~
  23.   RCC_DeInit();
    % f* B/ L- v3 w* z1 ?0 N3 @5 c

  24. 7 Y6 x9 i5 k/ Y1 m
  25. ( B% |8 {; ~& O# ^9 i

  26. + S  Q# A  {4 F
  27.   /* Enable HSE */' i9 B5 p' w) z% W' `( X

  28. 0 y! `( f: P* }2 s
  29.   RCC_HSEConfig(RCC_HSE_ON);
    ! |7 t0 ?( s8 ~+ T# h
  30. 2 h  Q- c1 y4 o! Q; Z/ g' z! ^

  31. 3 ?  Z: F4 _  M  o4 o: s7 M
  32. 7 Z' A5 m  M+ x/ n9 L4 B5 H
  33.   /* Wait till HSE is ready */
    4 e7 ?' p% b6 X; |1 f

  34. - e8 B. l4 `. M" U0 `$ H+ [
  35.   HSEStartUpStatus = RCC_WaitForHSEStartUp();7 M' e, c1 @& m! D- W$ v8 ]
  36. 2 P$ G  e- ~1 \& R

  37. 6 y2 E. T( W0 i3 e% s

  38. 9 {0 j7 O& r" n1 P1 I, Y, b# `
  39.   if(HSEStartUpStatus == SUCCESS)
    , w) u1 K2 S! q4 z5 k8 H& Z5 z

  40. : r) O9 K/ q. Y0 T+ _( c( v
  41.   {  }" d0 ]4 v( d) g2 s$ n: \* x
  42. ; e) \( ~2 {1 o5 `/ f
  43.     /* Enable Prefetch Buffer */
    + w+ @& ]' s! c6 q: Y. P1 [
  44. ' Z' l0 w' @8 o  P2 B: ]
  45.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);7 M% V: R+ O3 h. Q

  46. : t$ Q* t( U( [1 O7 p: x
  47. + L  A' H8 |9 _5 l+ F! d
  48. % j2 s1 X: u; i2 C7 f- z, [& e
  49.     /* HCLK = SYSCLK */
    / S& R# h' [3 y
  50. # M/ l' W4 Z' s  |. c( h3 Y) I
  51.     RCC_HCLKConfig(RCC_SYSCLK_Div1);; E* [1 K# N- D9 X
  52. : E6 k7 e/ E# J" T6 ^
  53. * g% k$ W8 q+ k) }/ _/ f

  54. % G6 ^6 |4 e9 `
  55.     /* PCLK2 = HCLK */7 l6 c8 P; n6 J! ]

  56. 2 C" e! J" @3 h1 L/ }7 U$ \$ f( Q$ {
  57.     RCC_PCLK2Config(RCC_HCLK_Div1);1 a+ E" o" Z* k  L" V! m+ @
  58. 7 t9 g- m3 O/ `/ o3 v

  59. - _! H' _  ~# \9 g
  60. . o! ^" p$ ~/ a" }- v+ ~$ q, g
  61.     /* PCLK1 = HCLK */9 `- g* c; Q, J! w9 K, O* C

  62. . |  M' _7 x! }5 ?+ X
  63.     RCC_PCLK1Config(RCC_HCLK_Div1);
    9 w, k0 z4 t; R  g7 v$ p1 G

  64. * e1 ]* z' n4 b0 T% r' t& x; G

  65. ' q* G4 @* m! l4 v% {: W

  66. 1 ^. c# \9 Z, ^6 o6 Q
  67.     /* Select HSE as system clock source */
    ) k  G% f2 z$ w9 }1 Z
  68. ! k- V' V% y" [( ^) x: r' f" ]! V0 q
  69.     RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);* S  q% J2 M3 O& }1 H

  70. ; X8 B! H& K* ]  L+ h& N

  71. 9 s3 E' d0 C0 }5 ?: V! Q
  72. 8 d$ ]8 {6 J0 ^6 N6 ^2 l2 P) E% u4 X
  73.     /* Wait till HSE is used as system clock source */
    ; U3 o& b8 o! U

  74. 2 h9 X5 a) e# i/ t
  75.     while(RCC_GetSYSCLKSource() != 0x04)
    - S, E/ X- @8 |4 Y1 o! c3 j& M9 {
  76. 7 ?  L; Z* Y0 k
  77.     {& J/ G9 x* V# V( l0 L: A

  78. 7 U6 `0 |. N3 u0 K, n4 ?8 g% n
  79.     }
    1 g& l6 r/ D1 q; K4 A% C' S( k

  80. % ]* S. i6 j! A/ b. E* }
  81.   }
    $ G' Q) s" u# n7 F# i
  82. 4 u5 S$ I, F$ x
  83. XXXXXXXX;    //分别为其他外设的时钟配置。0 w% x- K6 G9 {5 i( e6 R$ s" F' C

  84. ; @5 w! H7 k$ R9 j/ w  @
  85. XXXXXXXX;8 }. s. S" B; J  Y+ q

  86. + {+ ~" }8 t" d6 f8 U3 Q  P
  87. : E) _" I* x4 U1 B& C

  88. 3 x8 o5 e6 F) {7 B( J/ s- v
  89. XXXXXXXX;1 u0 j$ ?7 g( F8 H9 M0 m
  90. ( s6 D; ^/ q/ G7 e
  91. }
    ; |! u  j6 h: T
复制代码

1 [1 ?1 h/ x+ x/ Z
1 n* i; e: y, q! d二、关于PLL设置4 R  d- c6 B8 r/ }6 }; e9 J
. e+ p$ f3 o, Q( Q5 y9 g( I
PLL的设置主要通过函数:void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ, uint32_t PLLR)来实现。
1 j; S  d2 x7 ]+ v. ?' K% j
2 s  P# Y+ P7 j主要讲一下PLL值的设置与各部分时钟的关系。函数中涉及到6个量的设置,第一个为内部时钟或者外部时钟选择,后面几个为PLL值的设置。
* E5 y! ]" ]! {' }4 I, F# o; Z$ r$ u7 o" ~0 i
l  RCC_PLLSource选择:
; z" [) J6 w0 h. Y
0 S2 v8 n; C; D* QRCC_PLLSource_HIS:HIS内部时钟选定,频率为16MHZ
, |! |& r6 o* I% ~8 F+ R9 G: v
1 T( }1 `  [1 e# b7 O' I: d% MRCC_PLLSource_HSE:HSE外部时钟选定,频率可自选,4MHZ-26MHZ之间,系统默认25MHZ,如需改变,则对stm32f2xx.h中第70行的4 D% ?# x0 W9 c+ f$ d

( c! d3 E8 D- B# M5 _- Z#define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
7 @2 w' j3 G: N. d$ z" J: C. f- {9 K' @
进行修改,改成外部晶振的值。
: j/ C, O) g8 l. g4 Y/ @( W
  H1 Z& t; w8 R7 w4 v4 jl  通过选择PLLM和PLLN,来计算得到PLLVCO,计算公式如下:; x6 @" y, @% G0 K

9 N! C5 i+ _6 NPLLVCO = (HSE_VALUE / PLL_M) * PLL_N。7 `2 ?/ _9 o( k& A5 A/ ?

6 O9 n, v& [/ E& N) iPLL_M可取0-63,PLL_N可取192-432。
! n( u. d6 P) ~6 W
6 ]5 P8 E+ u) q& Nl  通过选择PLLP来选择分频数,以得到系统时钟。计算公式如下:( n2 B2 `9 m* p" ]3 |

! W& l( ]$ J! H$ I4 y* lSYSCLK = PLLVCO / PLL_P,切记不要超过120MHZ最大频率。
  l) D# a, t  p" E
  D& ]6 A2 s7 APLLP可选范围为2,4,6,8。1 u% e( y# ~! c$ B* y* W

4 p! b% M, J+ p: t1 ^! \l  通过选择PLLQ来OTGFS, SDIO和RNG的时钟。计算公式如下:
: C7 U' C$ s  t! }; {+ S
6 q" S+ `* `3 t5 E! DClock =  PLLVCO / PLLQ,不能超过48MHZ。9 {* ~# W  K/ H( U6 t
7 }8 V! U* l& y$ Y% w
PLL_Q可取4-15。
: U, H, V2 K2 R4 Y3 ]) L* {5 D1 S5 Z0 ~
l  通过选择PLLR来决定I2S的时钟。计算公式如下:- X) u& q1 [+ U5 j  Q, x4 S
: C$ H9 X7 \8 e+ n
I2SCLK =  PLLVCO / PLLR。/ r- v. {4 h4 u/ l
2 |0 O% y9 }( j
PLL_R可取2-7。
6 V4 w/ P& D( ]% E: f# o4 F
# d8 {  O' h) h1 Q& E# J
, ^9 A: S' B* B5 Y$ [+ n9 Z- N( `8 V1 T) p$ n
收藏 评论0 发布时间:2021-12-1 22:23

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版