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

STM32F207时钟系统解析

[复制链接]
STMCU-管管 发布时间:2020-9-7 13:46
下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的。( D; b8 N( w. m! X( r& H; m& H0 f) {
) ?& T$ R0 T/ o1 t+ N
01
时钟系统介绍
1.png
0 z) [- l% |. U$ l$ ?9 Y
7 _$ W$ E0 R+ h
▲时钟系统专业名词缩写
) X+ W8 `+ {6 W, G9 L+ e0 U$ P7 `1 r
时钟系统关键组成部分
5 P8 J' d# H5 `
$ Q3 z0 }" p% |# E  S3 i

6 }( F: B1 w) Q3 Y01 内部高速时钟(HSI)

# M% ^6 g1 X9 w- S
HSI时钟信号可以通过内部16MHZ的RC振荡器产生,可以直接用于系统时钟或者用于PLL输入。
) I. O8 L# J; C) y+ e$ n
HSI的RC振荡器的优势是:在最小成本(没有外部器件)情况下提供一个时钟源。它的启动速度要比HSE晶体振荡器更快,但是即使校准频率后,它的精度仍然小于外部晶体振荡器或陶瓷谐振器。
9 N$ Y3 j, t. |, K

$ `) J& a' C: V7 N+ |' `02 外部高速时钟(HSE)

1 N7 S& R3 B, G2 N6 Q* m- z  D8 \9 I1 \* _/ V5 }7 n* `
外部高速时钟信息(HSE)可以通过两个时钟源产生:

4 d( I$ H- V% k4 o; T
① 外部晶体/陶瓷谐振器
5 H" Z. u: W0 a! G$ M# e3 z/ r- |$ j( x
② 外部用户时钟
9 R# Z! ^( Z7 B- m
22.png
▲两种时钟源接入示意图
2 v' v% h; o! s) ~3 u
03
主锁相环时钟(PLL)9 D0 b& n1 i* Q( f6 L8 C* \+ R, a
9 ^) N: z; e6 L6 B
STM32F2xx具有两个PLL

2 t% V- l8 V. x$ o' _! |$ x
① 主要的PLL通过HSE或HSI提供时钟,并且有两个输出时钟;

7 P: z8 V. V, Y4 J6 L. O: d: s$ |( K6 |
② 专用的PLL(PLLI2S)被用于产生一个精确的时钟去实现高质量音频效果在I2S接口;
- i+ `0 B6 [" t/ h! Z' i7 d- g0 I
3.png
" H; q, L; ~# w
HSE/M*N/P得到PLL时钟
关于PLL锁相环说明

& u' [; i; n! Y) _0 D$ g7 G
4.png
$ O) ^9 ^5 n) L0 {7 i
从1处输入,3处输出是1的N倍。
3处除以N又作为输入,当1和2的频率一样,就锁定了。(之所以图上是xN,因为从2看向3的)
04 低速外部时钟(LSE): F! x8 Y7 Q! K" W. c- w
, f0 r9 u; C# @
LSE是一个32.768KHZ低速外部晶振或陶瓷谐振器。

) I3 s( H4 N! e" U9 I, c3 b* O
它的优点:提供低速但是高精度时钟给RTC外设,为时钟/日历或其他时间应用。

+ \/ ~! m% z/ n- D) ^5 ]7 s- G05
低速内部时钟(LSI)
: a* v) s/ q0 h) z+ b: A2 m$ p+ @* m8 V, v* t. _! ]
LSI RC作为一个低速时钟源,它可以运行在停止和待机模式中给独立看门狗(IWDG)和自动唤醒(AWU)。它的时钟频率在32MHZ左右。
" b& E% T/ P' c, l# ?" D+ P
02  代码分析
6 b) t) k1 T" k- Y; x2 M
时钟初始化代码在system_stm32f2xx.c文件中,大部分时候我们不需要修改时钟代码的,各个总线的频率我们可以在文件头看到。- |+ k4 V. X2 R* W$ u" h
* P) x' o! k# l
1 P' x- X! G7 H' B( s) X' O4 F! \
  1. $ i. r8 x3 {' t$ V6 o5 V( W" J" A
  2. =============================================================================
    , V* p' H3 J# h7 p8 o. j
  3.   *=============================================================================
    , N& H) s( A% q# I  i
  4.   *        Supported STM32F2xx device revision    | Rev B and Y
    ( g8 s7 U' b) L1 s" n6 Q
  5.   *-----------------------------------------------------------------------------/ U/ p! T; Y9 m0 s
  6.   *        System Clock source                    | PLL (HSE): V8 _' c7 @  S0 g+ }& U
  7.   *-----------------------------------------------------------------------------3 {! [) X# J$ u' B1 U+ N$ x
  8.   *        SYSCLK(Hz)                             | 1200000000 M. f3 u3 @# \% h
  9.   *-----------------------------------------------------------------------------
    . d! s6 S! c% {
  10.   *        HCLK(Hz)                               | 120000000
    + h' u- B7 a6 E$ t3 i( f
  11.   *-----------------------------------------------------------------------------3 d1 o6 k0 @1 J/ E+ F& Z3 b3 V$ p% C
  12.   *        AHB Prescaler                          | 1
    , g, ?3 v! H2 b) w- D
  13.   *-----------------------------------------------------------------------------+ z) A- }) x( }3 Z4 |
  14.   *        APB1 Prescaler                         | 4
    6 D" q+ P8 r2 I5 ]8 j0 ~
  15.   *-----------------------------------------------------------------------------
    4 w. S# g; H3 r0 g
  16.   *        APB2 Prescaler                         | 25 l% _9 ]3 x$ v+ e
  17.   *-----------------------------------------------------------------------------
    : Q3 j: ]) Y) [. u: y' n
  18.   *        HSE Frequency(Hz)                      | 25000000! Q% R  ]: Z! V* D$ f3 w& K- Q
  19.   *------------------------------------------------------------------------------ }/ a. C$ Z' N+ \7 {
  20.   *        PLL_M                                  | 259 W* F. W$ @: Z7 r( b! k
  21.   *-----------------------------------------------------------------------------
    : L5 `  o, B: {
  22.   *        PLL_N                                  | 240
    8 L  u2 Y& S4 S9 S9 B6 Y& Y/ V
  23.   *-----------------------------------------------------------------------------2 C" q# e& E# |, H
  24.   *        PLL_P                                  | 23 ~: ]$ y* i, K0 W6 w
  25.   *-----------------------------------------------------------------------------3 r, C7 e2 L6 U& }5 P' {
  26.   *        PLL_Q                                  | 5
    8 r5 f. k$ y* ~# K' J
  27.   *-----------------------------------------------------------------------------4 {) _9 M8 J* v5 i) v. L
  28.   *        PLLI2S_N                               | NA/ O0 C1 e% p" g- f7 \
  29.   *-----------------------------------------------------------------------------6 V- d' ]/ s% Y" J& e6 z
  30.   *        PLLI2S_R                               | NA8 g6 R6 ^/ b! r% D
  31.   *-----------------------------------------------------------------------------
    : U+ i# ^+ U& r5 U
  32.   *        I2S input clock                        | NA
    ; r3 u* X. ~+ i6 t. {$ K; z$ f
  33.   *-----------------------------------------------------------------------------% g* I4 L7 M. ^  Q
  34.   *        VDD(V)                                 | 3.3
    % U& I0 f4 i0 i+ ~, q
  35.   *-----------------------------------------------------------------------------  ^1 T) m( g) p9 {$ p
  36.   *        Flash Latency(WS)                      | 3# ~% D2 |% G/ M7 k6 a( G" `
  37.   *-----------------------------------------------------------------------------6 k% c, Q( Y6 G
  38.   *        Prefetch Buffer                        | ON& X9 d0 m, u" w3 D5 V. u
  39.   *-----------------------------------------------------------------------------  K8 z! T7 `+ O0 \2 R" z. T4 S
  40.   *        Instruction cache                      | ON- A2 [( i2 L; K( B0 ~
  41.   *-----------------------------------------------------------------------------
    9 [5 ]  l( E# B4 Y+ j7 l4 M) ]. w
  42.   *        Data cache                             | ON
    4 M) a8 q% x' u  k, z
  43.   *-----------------------------------------------------------------------------
    1 {8 i4 V7 g3 W9 u: X
  44.   *        Require 48MHz for USB OTG FS,          | Enabled
    + d: w' T8 B9 J: H& r/ _, Y6 \
  45.   *        SDIO and RNG clock                     |
    . B# {' L; o- G0 m8 B6 ]
  46.   *-----------------------------------------------------------------------------
    ' S5 O0 G) F* u
  47.   *=============================================================================' o0 S3 \+ j8 ^. I
  48.   ******************************************************************************
复制代码
6 g7 U! L- {3 B& M& j
5 Y7 w5 O5 Y8 k4 _
( L2 u4 k% Z; T% g: q% t  a4 l# A
5 L1 u' g7 G! W* s4 H

' j/ D3 L9 P/ @% @+ a
在文件开始定义的有系统时钟频率的全局变量SystemCoreClock,其他地方需要时钟频率,可以直接使用该变量。

2 j/ X6 l+ w2 G8 H' L! D
7 X3 f) K8 D1 k& w* r3 G
  1. 2 g  ^! {9 @" W, D
  2. uint32_t SystemCoreClock = 120000000;
    + v& \# R0 K  O6 G9 T5 o
复制代码
$ ?- F6 b& y+ J$ ~% f, O
+ ^, s1 S5 L6 K  s2 W
时钟配置从SystemInit函数执行,调用SystemInit的在汇编文件中startup_stm32f2xx.s(Keil编译环境)。

" W" Q% S" ?. D, F% X' l

  1. 1 k% y3 z0 o( m7 @: B3 |
  2. IMPORT  __main
    2 K* f7 H$ s; V. ?3 F/ P5 l
  3.     LDR     R0, =SystemInit
    ( Z0 ?, V- P6 ~" G  c# X- ]8 P
  4.     BLX     R09 i* h  ]! n) \6 s+ L1 T" z
  5.     LDR     R0, =__main
    9 ~* S, ?4 M: x8 x* Y. u
  6.     BX      R0
    ( ?" ~; F* J- K
  7.     ENDP
复制代码
6 O* L: Z" Z: R; p0 l

+ Q7 \, F6 v! Z5 {9 D

; {& r# E- p# N) k8 \0 z! Z6 G- b

) {5 r" J9 l/ ]% B8 E+ V
在这里说明一下文档版本的问题:1 ]0 \: f6 {1 ]4 ]* }! S
5.png

1 ^* s0 R. E1 h( d& y9 S+ \
▲STM32F20X_User_manual的V7版和V8版对比图

+ l( B+ O2 D( U
上述两图的区别是系统最大时钟从120MHZ变成了168MHZ,我的理解是同样是STM32F20X,ST由于技术进步或其他,使得新版STM32F207芯片超频支持168MHZ。

$ M- d  q. x4 h+ T3 l5 r下面我们主要分析SystemCoreClock的120M时钟怎么从一个外部25MHZ的HSE得到的。
. ]; E0 ?$ |& f: k1 P& A# b) f, }( T# A
6.png
* W* N8 K+ K3 N! f  w2 t! H& Y
我们要从25MHZ的外部时钟得到120M的系统时钟,需要上图中标注的重要4点:
2 q( M/ n9 J/ \6 \' s2 q5 r* M3 r
1、使能HSE
4 J/ p* c8 o7 z) y
2、选择HSE作为主PLL的输入时钟

* r8 l* f$ r% H: L
3、主PLL倍频后得到120MHZ时钟

7 H; ?: W! Z" r2 Y
4、系统时钟选择主PLL时钟输出作为系统时钟

' {: a: D' v( y
我们找到对应的代码

7 J7 S% k4 z2 {6 F+ P- d8 ^
  1、使能HSE" d6 u# P( O' E. {
  1. /* Enable HSE */
    # F; _# [. A. U0 L5 F& A4 y! ?
  2.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);
复制代码
6 j" @6 E( q0 `
. [# S/ P5 Z2 m5 L

9 Z. I) b9 o9 u+ R' x! O3 @* [
在RCC_CR寄存器(RCCclock control register RCC时钟控制器)中,有打开HSE的控制位
1.png

" f4 v3 C8 U/ Y2 E8 f
0 |% a$ x% n5 C; g8 H: O

$ ]1 B/ J  i- t+ h
2、选择HSE作为主PLL的输入时钟

4 t7 g9 \: P; d

3 Q6 l* q" D% `6 y

$ H; M. l/ b7 B2 ?6 L) A

  1. / H- k" J- p* ~0 E  K
  2. /* Configure the main PLL */
    $ Q2 \. U6 G6 J% t% M
  3. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    + f  Y1 r9 e8 x& `
  4.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
复制代码

; F0 Z+ h$ Y/ F9 d4 B  h) J
, q6 o3 N& \% V

7 D% C3 m3 Y* K6 p/ M6 g3 s% t/ i+ z. r( V7 X

/ J  S+ c$ Y. ?3 R" o
RCC_PLLCFGR_PLLSRC_HSE就是配置HSE作为主PLL的输入时钟& t# ^( k1 Q' L6 i, p9 R; a* a" L

/ g9 g2 ]9 A0 g/ ]4 }9 u

# X9 J4 m1 `6 F  a9 Y
  3、主PLL倍频后得到120MHZ时钟

4 y% R+ {+ k8 @7 K
  1. ; Y" M$ I+ |1 O# Z2 E
  2. /* Configure the main PLL */. `9 w( d) h- h; b* F
  3. RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
    ! K/ `8 H$ m* W  X- N* k" `' m* O
  4.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
复制代码

1 O& @# t2 ~. b& x0 g3 D: O1 X5 B& x1 A
8 @5 `6 C( M" R( r9 o; t
4、配置主PLL作为系统时钟的输入时钟
( M0 X% @/ Y4 L1 j
  1. /* Select the main PLL as system clock source */: L$ b& J8 @3 t& h3 o$ J, `1 M
  2. RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));# I( J3 l/ e8 T. A
  3. RCC->CFGR |= RCC_CFGR_SW_PL
复制代码
! ]0 n) |# i# ^' X
" E6 w  L  y2 I
对于主PLL的配置寄存器,在RCC_PLLCFGR寄存器中有说明
2.png
' r/ N1 E2 \# @
  _+ @& O- Y% T7 K7 I7 W/ q
整理后得知f(out)=f(in)* N / M / P

9 c5 F  f- K7 G: x
  1. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */1 Q3 O6 w4 ~9 Q! X/ d$ c
  2. #define PLL_M      25
    ; s" k; H+ k) i* I+ ~
  3. #define PLL_N      240
    1 B) r5 H7 [- k' g- I; {) z* Y9 O

  4. 2 p: ]2 S6 m/ x+ |9 H
  5. /* SYSCLK = PLL_VCO / PLL_P */
    ' f! Q- |/ T. E* \
  6. #define PLL_P      2
复制代码
! t0 u+ W$ Q. l

3 b0 H/ |6 x0 V" ?8 Q7 @
这样就获得了120M时钟
/ N$ b$ w6 U7 `$ J1 u

& @$ F4 [3 `4 w; H* y0 n+ M

! a! K1 k" J8 i

, u, c0 j' ~, R0 ?
注意:
7.png
PLL_M大于等于2且小于等于63
0 [0 \/ u# A! ^7 `) o4 q5 I1 y* k4 |9 s
8.png
PLL_N大于等于64且小于等于432

% v/ i+ m5 {: r% a" [, |/ l: w7 K
9.png
PLL_P只能是2、4、6、或8

, k. N* t( Z  h. F+ ^" {& I3 K
但2对应0,4对应1,6对应2,8对应3。

4 J" X/ h) h7 n8 @. x- R6 u
ST并没有使用if或case语句判断,因为对应的数据除以2减去1就是寄存器这两位的值,所以可以按照下面这样写,这种写法值得我们学习。

9 V) G8 \) y! c  u( g
  1. (((PLL_P >> 1) -1) << 16)
复制代码

9 P! Q8 C! I- j% y
! b6 D1 d1 k, o7 B& N5 R
其他外设的时钟配置时

  o! i/ f* z- F) G
  1. 7 ]3 R) q  b( V+ }8 w( C3 r2 U
  2. /* HCLK = SYSCLK / 1*/
    ( I) a% h$ P) F) O; T! W! w
  3. RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    % w: Y& o2 Y, b1 q% W4 f

  4. 3 g; @- O8 J; R
  5. /* PCLK2 = HCLK / 2*/9 a( J1 k: j  f( M# M/ Q0 o+ d0 M. l3 `
  6. RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    9 `6 F6 a( i3 u& v* L% D" h8 ^

  7. 5 }2 @! f; n" }$ L3 b+ l' [) Y2 b
  8. /* PCLK1 = HCLK / 4*/4 q! k3 P) \3 C3 w2 e; f$ J
  9. RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
复制代码

: I* l" l& h+ d( A1 C
0 M7 }+ N% Y$ d( ]" c3 m8 _; v
" ?! D4 M+ w- }  e; j

9 H& S% K; f% ~% ~$ d
备 注

$ V6 @& ~3 d* n3 g9 N/ B6 z0 S6 h/ A+ u# [
' f, q- m( Z) O2 |& H6 b
7 w5 }5 Y9 p+ v, T3 X$ t7 H
时钟中断
& s0 _8 n" c: o# I4 U8 s' p+ t
10.png

# w( y  k7 |& y7 z; I$ u
可以配置外部晶振出错时的中断,还有RCC中断,因此我们可以在外部时钟出问题时,切换为内部时钟,不至于整个系统挂掉。具体见ST给的官方代码。

8 r9 Y, E) k- w; V. S# m9 X
& D' ]( ]2 u9 G3 M3 m
无源晶振不起振

  `, @0 |* m" z# U5 S' R1 g( S
没有程序,无源晶振是不起振的,需要配置RCC时钟控制寄存器的HSEON位打开或关闭HSE振荡器。具体可以看之前的文章《[color=var(--weui-LINK)]晶振原理解析》。

: `- O+ ?( r7 c6 `' z4 e! \2 X- Q4 S7 a, i
关于APB和PCLK
! w4 ?/ v1 T3 \! ^5 T; ^; A7 v
F207是时钟图没有显示PCLK1和PCLK2,应该就是APB1和APB2
应该指的是一个PCLK应该是PeripheralClock的简称,看F105手册
  `' r3 M: G! ?; q, q
11.png

3 [/ o7 A- t5 m2 `; X* ~8 p, y- m0 z

& ^1 i" {; `0 Y; J% ?8 i) l$ ~; j$ B, H3 F' o. _8 f# f3 o

4 D6 Y; ?$ Q% V+ S2 F  B
赞 收藏 评论0 发布时间:2020-9-7 13:46

举报

0个回答

所属标签

相似技术帖

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