EDA365电子工程师网

标题: 送给新手:STM32的时钟树解析 [打印本页]

作者: liao821    时间: 2015-11-12 09:56
标题: 送给新手:STM32的时钟树解析
STM32的时钟树
' M  X- T$ u+ J         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
/ b1 X0 i5 a! g1 x% u. o! @   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
! O1 ]( u8 U) r6 f4 n0 \         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。! K& u( p3 c# P* M3 C0 e5 W
标号            图1标号释义
4 ~* D, _5 Q" ^7 ]1     内部低速振荡器(LSI,40Khz)
  v+ r% |6 @$ e; `4 y5 O" W+ E6 \1 k2     外部低速振荡器(LSE,32.768Khz)
1 G1 H, r; W, ^% g3    外部高速振荡器(HSE,3-25MHz)
7 l- B, T" F0 s# X% C: j, G4    内部高速振荡器(HIS,8MHz)
+ Y$ t  P9 N$ h  p/ J' s7 N% y; T5    PLL输入选择位% g2 L; F- X. u; Y
6    RTC时钟选择位% E0 W4 V- O8 G, a9 [. R% N
7    PLL1分频数寄存器1 S, t3 N- |. w; I
8    PLL1倍频寄存器
& [; }! g) I( q. ]! m  u9    系统时钟选择位, q* O% g6 \/ Q& e/ f
10            USB分频寄存器
0 i. j9 G% B3 L. P* X11            AHB分频寄存器
5 ?  _0 r; ]  e* Z12            APB1分频寄存器" ]' E* P. z! z. ]" `
13            AHB总线2 Z0 l6 B. z3 q/ T! V
14            APB1外设总线5 `$ }% B, @- G- h) H. G( D2 _
15            APB2分频寄存器! m' m/ k5 b2 ^+ {2 _% L
16       APB2外设总线
9 n2 s0 r8 `8 [5 t0 @4 d17            ADC预分频寄存器- J! s; y  U6 k4 J# S
18            ADC外设
# ?7 f. ~: {; i7 _# U4 t* {5 w19            PLL2分频数寄存器2 R! Z$ t3 Z  D2 P- O# q
20            PLL2倍频寄存器
! Y; y6 d+ }9 S; t  U21            PLL时钟源选择寄存器9 y1 r3 g( }% ~
22            独立看门狗设备
, W6 |" i" E- E% ~23       RTC设备
: e1 O  q/ ~, n1 X7 LSTM32时钟树.jpg5 r7 G/ }) W$ Y. |
图1  STM32的时钟树$ G# ~3 Q# U7 Q" }* w0 |6 F* N7 r
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:$ h5 f% Z$ ]4 ?# [' I- n: Z
3——5——7——21——8——9——11——13- _) K" ]6 Y0 K! W; O
对此条时钟路径做如下解析:
; @/ e! A# [8 v* o1 [9 [对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;# k5 R- @  w! }2 T
对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
. Y$ \# @6 z# g! M6 w( C( i  |对于7,设置外部晶振的分频数(假设1分频);
$ f3 L4 \- _( x对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
4 B5 h0 X% Y( o& E: ?对于8,设置PLL倍频数(假设9倍频);
1 X2 f- R4 Q9 T3 L+ J# [' c对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);& T% b, k$ E/ X
对于11,设置AHB总线分频数(假设1分频);
7 \$ }( K& ]5 M2 j) i5 q对于13,时钟到达AHB总线;
4 R" Y$ ]- V9 Y9 j在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:9 B" }4 `' r  q" P0 g) T
3——5——7——21——8——9——11——15——16+ \- W0 p2 ?! c) [3 W, W" U
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;' O( Y9 k  U6 m1 x# W
对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);' z$ J0 \! B3 K5 U( C$ X# }
对于7,设置外部晶振的分频数(假设1分频);1 e* G4 B: @5 n
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);+ y& l9 A6 @, G; E% h& |! G* W+ K
对于8,设置PLL倍频数(假设9倍频);9 m9 \- D+ n7 ?" G0 B2 X
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
% `3 E! ^' N& V, t4 f对于11,设置AHB总线分频数(假设1分频);
& ^7 n, Z: d6 }  s' v: x对于15,设置APB2总线分频数(假设1分频);
# t( r# i3 F4 q% C0 E0 t对于16,时钟到达APB2总线;
% s  |1 D/ g. S. N& M/ T, ?3 ~现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):1 v) f/ h; U# G% S
1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。5 ~1 j; n9 b$ ?* w( ~+ b( Q- f
2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
1 z0 y( t/ b0 k6 U6 Z3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。
6 ]+ \- `7 u9 ?  L6 b4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。( `. m' m1 D, k" p8 b- S1 ~
5)   时钟到达APB2总线外设。6 R; @) A, }0 y# [; a
因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:- d4 e! o) O$ w$ s+ L" r8 e) c
void RCC_Configuration(void)
* J: e0 `$ o- ^# [0 k{
- c$ I* L3 M) {; j3 L! q        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
( g/ _6 q+ O; T: R, w2 z        RCC_DeInit();                                                             (2)0 Z2 \; r- h1 S; y5 W: C2 a
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)
) F8 ~. G2 _) U  A- {% s        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)2 v9 y" v8 P8 [' J  @- A8 b
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)
! k: y, q& j8 Q5 E( i5 R) o( o        {5 p1 [0 Q1 b, E. i% r: _) n. Y
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)) G( S0 z( L% f& B
                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)) r5 F! h; n8 D' ?: ^
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)1 S! p5 I; T6 Z4 q
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9), z6 `8 {  f; n- i# A
                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10). x* G2 p/ B: R( I
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11). j, s# a5 Y& s( W# o6 d
                  RCC_PLLCmd(ENABLE);                                      (12)- X" c% T# i4 w0 y2 _- a) R
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)
8 L8 J4 h3 Q; {3 a4 u                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14): j: F7 l: o  n- \/ t6 E" Q
                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)
; r1 ^& R8 y' W7 }. K: v        }: H- ], g& w; |4 P  P3 n# Q

作者: Haiting32451    时间: 2016-6-4 15:48
学习中,谢谢分享& ~2 w8 n4 G+ N" B





欢迎光临 EDA365电子工程师网 (http://bbs.elecnest.cn/) Powered by Discuz! X3.2