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

STM32F207时钟系统解析

[复制链接]
STMCU-管管 发布时间:2020-9-7 13:46
下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的。
0 e/ B$ [/ R! q; c+ _1 A5 N4 o
8 C! Q, @& w, Y# v5 Q
01
时钟系统介绍
1.png
0 K1 t* v* t* H6 w5 ^. u

. d+ B, Q% X8 N2 }$ a. k
▲时钟系统专业名词缩写
& u  p% _3 Q( J. K9 E% k: W
时钟系统关键组成部分9 ~+ P4 r$ i& G5 w
! W5 I0 M0 K. K

7 U, \6 ]+ \4 {, \& ?01 内部高速时钟(HSI)

: `" D" \+ e" w: F, N& s
HSI时钟信号可以通过内部16MHZ的RC振荡器产生,可以直接用于系统时钟或者用于PLL输入。
) x- y' x6 m/ z! x4 @8 A: A
HSI的RC振荡器的优势是:在最小成本(没有外部器件)情况下提供一个时钟源。它的启动速度要比HSE晶体振荡器更快,但是即使校准频率后,它的精度仍然小于外部晶体振荡器或陶瓷谐振器。
5 r# k, G) W* F

! g$ z1 a: F% x# m2 o/ I3 C9 K- w02 外部高速时钟(HSE)
+ l0 @& v) |0 f$ P% i9 p7 ^
& n) F' V& I. b% j2 U4 H/ P: f6 B
外部高速时钟信息(HSE)可以通过两个时钟源产生:
& ^2 J4 z7 x; T! }& Q6 \/ J
① 外部晶体/陶瓷谐振器
% v2 J* e; p8 D0 O4 y
② 外部用户时钟

) X6 ?( W% [& j$ s
22.png
▲两种时钟源接入示意图

* R5 v, C& r, W3 w# u03
主锁相环时钟(PLL), p2 p3 u; B$ }  L( N2 J

1 i6 @2 V6 @+ r
STM32F2xx具有两个PLL
, p0 p2 o- b% `1 v; S
① 主要的PLL通过HSE或HSI提供时钟,并且有两个输出时钟;

: @) a6 `: j( Q0 Q0 n
② 专用的PLL(PLLI2S)被用于产生一个精确的时钟去实现高质量音频效果在I2S接口;
) y8 M: v1 l- j# c0 h% h) H
3.png
4 ?/ [6 K7 B6 {, x8 E! V+ i: t
HSE/M*N/P得到PLL时钟
关于PLL锁相环说明
7 X7 c8 f3 ~- b( k
4.png

9 R* T: ], N' d
从1处输入,3处输出是1的N倍。
3处除以N又作为输入,当1和2的频率一样,就锁定了。(之所以图上是xN,因为从2看向3的)
04 低速外部时钟(LSE)
! y9 S7 c: |9 a
- M& D+ H) N6 A5 ]% E% w
LSE是一个32.768KHZ低速外部晶振或陶瓷谐振器。

+ q" z- T1 h/ W; m: Z* R0 H
它的优点:提供低速但是高精度时钟给RTC外设,为时钟/日历或其他时间应用。
, J* n5 p" p+ ^' q( u8 o' T
05
低速内部时钟(LSI)
# t  W/ ]% ]5 q' K" M
9 n& C$ i- n2 `: `8 _+ u
LSI RC作为一个低速时钟源,它可以运行在停止和待机模式中给独立看门狗(IWDG)和自动唤醒(AWU)。它的时钟频率在32MHZ左右。

$ d% [/ @6 f3 w5 I; k02  代码分析
5 p" M: X/ ]: c( U" ?" L" X2 g/ V
时钟初始化代码在system_stm32f2xx.c文件中,大部分时候我们不需要修改时钟代码的,各个总线的频率我们可以在文件头看到。
( R  x1 a0 l0 X5 _8 J! |8 M: T% Z! v2 r) m5 t& \% L1 d6 _

; g6 I: v% d  ^. F4 [) b

  1. & p* D8 f- u, S% i! t+ g
  2. =============================================================================
    ; f! N2 n( {4 V* z/ @
  3.   *=============================================================================
    . C. l0 f8 ?9 Z% C5 R6 e1 l
  4.   *        Supported STM32F2xx device revision    | Rev B and Y4 o+ b7 e$ j. T' z. E. H* u
  5.   *-----------------------------------------------------------------------------, `% @; a; r; Y  ^8 y
  6.   *        System Clock source                    | PLL (HSE)
    * i4 D: ]# l+ V9 I2 [$ `
  7.   *------------------------------------------------------------------------------ p: N: J! G2 d& e1 D$ H( H% z
  8.   *        SYSCLK(Hz)                             | 1200000005 @5 ?- g8 P6 n8 V0 N
  9.   *-----------------------------------------------------------------------------
    / S" ]- c" Q, {$ Y9 v2 ^: r
  10.   *        HCLK(Hz)                               | 1200000003 j! }+ \6 w9 Q! e8 ^! V, w
  11.   *------------------------------------------------------------------------------ X: R" w. M% ~' b5 H8 }+ P
  12.   *        AHB Prescaler                          | 17 @! l# S( O4 [# M, ~9 a* e
  13.   *-----------------------------------------------------------------------------
    1 z" J& j; g* j  c/ [" `  ?4 x. P5 O
  14.   *        APB1 Prescaler                         | 4
    6 `0 V: X8 K7 i8 q
  15.   *-----------------------------------------------------------------------------% @& O3 w3 ?: b) [9 M) E
  16.   *        APB2 Prescaler                         | 2
      ]3 O1 H( Q- y
  17.   *-----------------------------------------------------------------------------
      h* e( R  @1 ]% ]7 x/ h
  18.   *        HSE Frequency(Hz)                      | 25000000) }! z$ x* U) b, I
  19.   *-----------------------------------------------------------------------------
    % Z3 C6 t0 |# d' A9 D
  20.   *        PLL_M                                  | 25
    & D; i. c+ O2 J! u4 k
  21.   *-----------------------------------------------------------------------------% ?3 S" B& E1 j, f& g
  22.   *        PLL_N                                  | 240, H# Z+ H' U5 d, T7 E
  23.   *-----------------------------------------------------------------------------" F; H1 o( b* \( Q6 ~- Z
  24.   *        PLL_P                                  | 2! x- Z1 O1 K5 R5 K5 E
  25.   *-----------------------------------------------------------------------------
    4 l4 A! B4 R/ B2 d
  26.   *        PLL_Q                                  | 5! t8 Z8 P: l# U) y5 f
  27.   *-----------------------------------------------------------------------------
    ) p; R, ], B) U! E+ Y
  28.   *        PLLI2S_N                               | NA* Y! |; {' X  p' T$ m
  29.   *-----------------------------------------------------------------------------0 z6 l  ]5 ^" C$ D% i) B
  30.   *        PLLI2S_R                               | NA
    - ?" ?: l# h! v# U* P8 @
  31.   *-----------------------------------------------------------------------------( m: f3 I6 U/ O9 D2 ^# n
  32.   *        I2S input clock                        | NA
    : x& O# T& O1 ]# @
  33.   *-----------------------------------------------------------------------------
    * D: v( }5 P2 E0 T/ }+ N5 z6 y$ e
  34.   *        VDD(V)                                 | 3.3
    2 G5 Z6 Z. s( q7 ?" H/ L7 F1 T
  35.   *-----------------------------------------------------------------------------
    9 v$ D" g( B5 Q& ^) R! l
  36.   *        Flash Latency(WS)                      | 3! M* w8 }1 b% T$ X7 X3 ]" Z
  37.   *-----------------------------------------------------------------------------$ E4 s5 V1 q- o
  38.   *        Prefetch Buffer                        | ON
    5 f' d1 b2 y/ A6 j
  39.   *-----------------------------------------------------------------------------
    * g# A1 |/ l$ P  T/ a! O+ b
  40.   *        Instruction cache                      | ON1 W: ~. p7 d4 s
  41.   *-----------------------------------------------------------------------------4 F! R) B) Y0 A; h0 n
  42.   *        Data cache                             | ON) @& l7 D6 p, C% |4 e  S& y* o8 j
  43.   *-----------------------------------------------------------------------------; p6 h! S2 o$ m5 U
  44.   *        Require 48MHz for USB OTG FS,          | Enabled* I( C; p" e- }! O- j$ R2 @/ n0 W
  45.   *        SDIO and RNG clock                     |6 x- i3 p) M# K& `% j  S, X
  46.   *-----------------------------------------------------------------------------
    4 _2 R) ]' s; K
  47.   *=============================================================================5 B/ |8 }! t- L: h9 M
  48.   ******************************************************************************
复制代码

( [( n3 E/ S, f' L7 o# I/ r5 |- j2 F4 u8 e/ u
, F1 Q& q6 p# w: Y

0 z) Y8 i0 ~  K  I9 ^( R" H% p7 \
- z, t) S& j! p7 B
在文件开始定义的有系统时钟频率的全局变量SystemCoreClock,其他地方需要时钟频率,可以直接使用该变量。
/ q7 ?" t( m- W7 G; V: n9 `6 ~
+ T0 |2 N9 e, c2 O8 N
  1. ) Q8 S8 ~2 O7 [
  2. uint32_t SystemCoreClock = 120000000;
    8 i  V3 M: }- k8 u$ B* z2 K
复制代码
+ t4 J; `2 E+ k2 n; C" `  j8 w6 s
) z$ i/ y. p; f8 k. x  l8 v9 c, ?
时钟配置从SystemInit函数执行,调用SystemInit的在汇编文件中startup_stm32f2xx.s(Keil编译环境)。

  F5 b* n! z1 k6 p! v

  1. & ^; |0 Z; Z' ^: e
  2. IMPORT  __main
    1 b. y& ?4 G) I0 K$ p2 J
  3.     LDR     R0, =SystemInit
    3 W( @9 Z: W& ?7 x
  4.     BLX     R09 c7 `4 \4 H/ K0 [
  5.     LDR     R0, =__main
    # ^4 H& O4 K# D. v( U
  6.     BX      R0+ y) t' @: M) Q
  7.     ENDP
复制代码
/ [  b0 J% b, t, s3 I8 v' e

& O4 f& b9 X" K! b9 Z0 t3 h! W6 j
+ F* t# k- w4 d. ]( x4 E! L2 @- T
8 B( n) c5 C# d! j
在这里说明一下文档版本的问题:
7 B+ c" {1 _: S9 _3 x* m* ?
5.png
2 h2 _! p2 i4 m7 L( R9 j( n( i
STM32F20X_User_manual的V7版和V8版对比图

4 A; S: w: z* c- A
上述两图的区别是系统最大时钟从120MHZ变成了168MHZ,我的理解是同样是STM32F20X,ST由于技术进步或其他,使得新版STM32F207芯片超频支持168MHZ。

$ ^3 J1 R0 w! }0 I下面我们主要分析SystemCoreClock的120M时钟怎么从一个外部25MHZ的HSE得到的。# _2 _8 q  L' P; L
. A4 i1 j) a$ X- T) J. `
6.png
  Y9 z6 f( V( Q7 r- ]5 l
我们要从25MHZ的外部时钟得到120M的系统时钟,需要上图中标注的重要4点:
7 v, ^, t4 \+ I# O! v
1、使能HSE

, [0 z) G/ ^  D* Z
2、选择HSE作为主PLL的输入时钟

6 e- q% Y4 k( L1 @! _% ?
3、主PLL倍频后得到120MHZ时钟
% E+ ~4 W8 L) U- }" t
4、系统时钟选择主PLL时钟输出作为系统时钟

6 i- h7 S+ k3 X
我们找到对应的代码
2 K3 N; l+ ^7 |( |1 e. |
  1、使能HSE# a# w  K# q; m# `& ?. p! @
  1. /* Enable HSE */; G! a. }, l" {2 E6 z1 v
  2.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);
复制代码
2 }) W+ Q, e. f& [4 \) I  B$ g- V# D8 ]
" L- c# w/ ^* F4 q1 Z

" s3 @" g5 a4 E, N; `3 y& q
在RCC_CR寄存器(RCCclock control register RCC时钟控制器)中,有打开HSE的控制位
1.png
4 F* x" i- j& s7 d) n

; d3 m  c  I, b4 O8 L. A* C) g9 R2 b, B( |, o* l1 k
2、选择HSE作为主PLL的输入时钟

  j2 }$ a# ?  c+ o

1 N6 u2 ~& w/ {/ R+ \& Z
* U7 I9 G5 h$ q. S8 u) u

  1. 3 z) j1 @2 u  B/ g0 b
  2. /* Configure the main PLL */
    / m/ b, r, ^: F
  3. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
      [+ u0 ?! X$ W2 n, U4 a
  4.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
复制代码

' \; \& C' U, v$ e& C4 R& }
' l2 w5 S! e& v- W- }. O4 Q8 M8 g

8 u- H6 j6 {5 y) ?- X4 y
  K5 s0 c7 F* q6 Y- s) u5 ]9 `" N! x
RCC_PLLCFGR_PLLSRC_HSE就是配置HSE作为主PLL的输入时钟
% [  {+ x6 o0 c& `
# G3 f! }0 h& N6 p

$ y* s% n' h' y" B
  3、主PLL倍频后得到120MHZ时钟

4 v/ F6 a8 t% z3 Z5 p; |8 O

  1. / M: `' F# c, F; r4 |8 L" j8 L+ H; C6 i
  2. /* Configure the main PLL */
    ) o8 O) o  |3 F" y8 m+ |
  3. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    % q2 K5 J3 D; R* |, d! y1 H1 R
  4.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
复制代码
/ W( K. }7 U' w$ J4 l9 {1 A% Y+ H# J

  U$ _8 A$ G4 s1 b
4、配置主PLL作为系统时钟的输入时钟
6 I( ~: {8 N$ a: x1 |2 t. B
  1. /* Select the main PLL as system clock source */
    : e) z. }; Q% O/ F( B; g
  2. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));6 U$ T7 w: S% }  @
  3. RCC->CFGR |= RCC_CFGR_SW_PL
复制代码

: _: ]$ y% I4 Q2 q
9 p6 W  c7 w$ B& Y- r
对于主PLL的配置寄存器,在RCC_PLLCFGR寄存器中有说明
2.png
% _8 W* q' \  t
% C4 p( p7 Q3 v
整理后得知f(out)=f(in)* N / M / P
3 p) A: I. p# h- c2 u0 h: c
  1. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
    ) g" [3 `/ u2 a. T8 c* E/ Q) m$ o
  2. #define PLL_M      257 P4 f5 K" Z/ ?1 @! T+ x
  3. #define PLL_N      240
    & j9 D' [' O" j: z* U- }5 F

  4. ( J+ b! ^# J  e6 T1 Z, F
  5. /* SYSCLK = PLL_VCO / PLL_P */# w% O; j" i6 M9 v
  6. #define PLL_P      2
复制代码
5 z5 u1 M& W6 i' [
$ c7 z  q5 q! r$ y) Q
这样就获得了120M时钟

) J5 `8 w! @' r+ w+ w# n3 A

, {) j% Z, a( C6 K4 I
4 @0 f+ \+ q0 ^' a) B

& o2 ^& m$ H3 ~1 Z2 B
注意:
7.png
PLL_M大于等于2且小于等于63
( c) X/ |9 \" U& h9 b% y
8.png
PLL_N大于等于64且小于等于432

0 E! L0 l) l$ z& J! j, ?$ \2 ?9 i
9.png
PLL_P只能是2、4、6、或8
  q. b% h: o2 ~0 ]% O
但2对应0,4对应1,6对应2,8对应3。

& x! D1 Z! B2 n" \: y5 ?
ST并没有使用if或case语句判断,因为对应的数据除以2减去1就是寄存器这两位的值,所以可以按照下面这样写,这种写法值得我们学习。

; s0 g+ M8 Y/ i: ?
  1. (((PLL_P >> 1) -1) << 16)
复制代码
3 S$ C6 W; z% O1 |9 V$ q7 c

4 ?3 b% V; ?: [% P; h% o7 c0 O2 C. M
其他外设的时钟配置时

6 r5 a# h! B/ |
  1. . ]% ^/ y) t. D# E; C
  2. /* HCLK = SYSCLK / 1*/( f& ~6 g% G/ ^/ i" z
  3. RCC->CFGR |= RCC_CFGR_HPRE_DIV1;) y! d! r, B5 {8 h0 _

  4. 8 N. b% R) }; ]6 r; p
  5. /* PCLK2 = HCLK / 2*/7 `1 `, w( E0 E, w' Z, N' z; w3 I
  6. RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;5 p7 U- T; r; T" {  x

  7. ' }- M! r% L  j9 E2 b& y
  8. /* PCLK1 = HCLK / 4*/( `3 u4 i  k9 _5 h4 r- u: |4 A0 X
  9. RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
复制代码
, T/ ]7 c' w! Q/ A/ m$ O' k3 ^
3 A/ S2 }2 a5 O; o
- ^/ Z9 e1 `; b
5 H4 F8 S# o  o$ L% C  W
备 注

7 P, m4 x' _2 d0 f& T9 M' R/ z
! c$ K6 j. E5 p. \9 A4 @) J, }2 x- P& T5 k5 N; I
8 G. z* Q7 e0 C) g7 i
时钟中断
' T, u/ l. w" f% d1 S8 D
10.png

4 W( Y$ P7 y6 J
可以配置外部晶振出错时的中断,还有RCC中断,因此我们可以在外部时钟出问题时,切换为内部时钟,不至于整个系统挂掉。具体见ST给的官方代码。

( ~1 T' H" M5 M8 L5 V! P  v! W0 d
无源晶振不起振

8 X3 C# m: O- D. G# _2 ^
没有程序,无源晶振是不起振的,需要配置RCC时钟控制寄存器的HSEON位打开或关闭HSE振荡器。具体可以看之前的文章《[color=var(--weui-LINK)]晶振原理解析》。

, t2 Z1 n6 _2 s' \8 a
5 i' g, E- Q3 o8 Z7 ?- b
关于APB和PCLK

& w* B8 {1 q' g  I7 ?  ^* u! r
F207是时钟图没有显示PCLK1和PCLK2,应该就是APB1和APB2
应该指的是一个PCLK应该是PeripheralClock的简称,看F105手册
, A7 E1 C& O1 e+ X/ m3 k8 e
11.png

# r5 J! G/ t5 M$ f
4 U' N# o- D$ [4 N8 u- w2 N
9 r, i6 n  z7 O" n/ f) B
/ q/ @' h* o! i" @& M( @
收藏 评论0 发布时间:2020-9-7 13:46

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版