找回密码
 注册
关于网站域名变更的通知
查看: 587|回复: 1
打印 上一主题 下一主题

送给新手:STM32的时钟树解析

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2015-11-12 09:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
STM32的时钟树
5 U1 `* L2 d5 q: I8 u! H1 I         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
% O+ [+ F% ]/ W) m   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
% d- F5 S8 l& u0 n3 f  ~8 E1 ^         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
7 h* v4 g) Y, g" `+ O' e2 `8 ~标号            图1标号释义0 g# Z) |. q" V
1     内部低速振荡器(LSI,40Khz)9 K, ]7 E! }% }$ U) ?" P
2     外部低速振荡器(LSE,32.768Khz)9 Z5 m" C" P" h
3    外部高速振荡器(HSE,3-25MHz)
/ i2 W7 Z4 E/ Z4    内部高速振荡器(HIS,8MHz), H1 z; c- m2 E8 s; ^! X. S
5    PLL输入选择位% M- o' w/ e9 r7 d* G# R
6    RTC时钟选择位# e" U$ l2 b* v1 @+ M8 n
7    PLL1分频数寄存器; k& s# p/ T4 ?4 Q8 ~: [
8    PLL1倍频寄存器2 ]. z' i/ [: s) z4 @% i; k
9    系统时钟选择位
) j/ D3 A- f2 |, B+ _; A8 S) [10            USB分频寄存器
* }' n* t1 A; Q( j  W$ `3 c( s# J11            AHB分频寄存器
" \0 G; t' m6 q  k- U+ J, V6 S, o12            APB1分频寄存器
0 |: N( F8 N* K" g13            AHB总线: c/ t& e4 G4 F* G. O. [  r$ \
14            APB1外设总线
: N8 H, g: l% q+ U15            APB2分频寄存器
" K) K6 X  r3 k0 Z* ^16       APB2外设总线4 I- X# p9 C' g# J# l2 L: w" R0 D
17            ADC预分频寄存器: B# q2 z7 r1 u& g& y
18            ADC外设
2 ~# d  J9 `: h19            PLL2分频数寄存器4 ?1 ^# G" m7 s# M( S
20            PLL2倍频寄存器! s- ^5 K" {5 O* g9 Z% n( l
21            PLL时钟源选择寄存器* }4 p* s1 t# Y6 f& v
22            独立看门狗设备! \3 z! S$ a* N( j, A2 u
23       RTC设备
: W* |7 Y4 t/ [3 K3 z. ]STM32时钟树.jpg
- [. f/ I( u7 ~: h  h7 j图1  STM32的时钟树
; |* f( I7 l+ T* C: u* w   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:
: N* I) Y1 ?- x7 [4 \5 P: I$ n3——5——7——21——8——9——11——13
" }% L7 i% L8 l3 t- A对此条时钟路径做如下解析:  M" e& G& X: C" n; Q" ?! u
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;# ~" N* u$ F, B' f3 r+ U* ^; E) ~0 w
对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);' n7 b# k' g* V1 C; _
对于7,设置外部晶振的分频数(假设1分频);
9 f' g) D5 \3 x3 K; O4 o% m# V1 z对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);' t! V. j# t/ d5 y
对于8,设置PLL倍频数(假设9倍频);
! T  c0 U* u- d/ ~1 c6 u对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);2 U+ [& ~3 n: h1 S- N$ r
对于11,设置AHB总线分频数(假设1分频);# \$ A+ `/ ^: _
对于13,时钟到达AHB总线;" T3 V( v1 a4 ?( K: p/ K
在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:
9 d9 ~: m9 q$ v3——5——7——21——8——9——11——15——16
" G5 S* N. s5 W对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
  l$ g' b0 R3 T( J( \对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
& I3 z/ e& y0 x0 v对于7,设置外部晶振的分频数(假设1分频);
( o  i3 _2 ]( K对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
$ y% A6 G* C- D2 {0 w! L对于8,设置PLL倍频数(假设9倍频);' q9 g1 @# X5 j: w
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);2 Z$ @8 T, J3 [- a, {/ Y" B# w: U
对于11,设置AHB总线分频数(假设1分频);6 Y: [% J) c6 U7 Y
对于15,设置APB2总线分频数(假设1分频);
3 o' i' s# |$ b2 r对于16,时钟到达APB2总线;/ I8 S* M' f6 R( s
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):* b9 e0 R$ L- V8 _! _) H
1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
; H+ q  D4 J! T  N( W) A5 N2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
( p# K( o! c: _0 P# f' @/ ^3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。; Z7 q! r4 P8 f1 z4 F
4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。2 E) `% ?" z! o% L9 u1 q7 t! V
5)   时钟到达APB2总线外设。
0 u, d/ B: b% ^/ @& t1 u( n' Z因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:/ O# G! ^; ?4 z- I
void RCC_Configuration(void)3 v6 m: {6 z3 T; |8 D& R
{
- h6 `4 ~( Z+ b% _/ j; g: b8 h        ErrorStatus HSEStartUpStatus;                                                                                                     (1)* z  m. P/ @; x5 L2 v2 m- s+ \
        RCC_DeInit();                                                             (2)  [7 e% l, Y1 H$ ]$ ~( o
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)* w1 U* Y* v$ l' c1 t* v
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)/ l  L$ f% s6 y8 O" Y* T
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)
1 Z+ v3 \6 H; J% L- R/ Z        {% }8 s$ N, u7 {, r5 j5 m8 O, J1 z( ^/ M
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)
  b4 d1 D( ~9 E% e& ?                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)2 n' G) h$ Q, A4 \: M  [; y
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)) u  ]4 ]3 }& k! e! L  x
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
6 @% v) P/ N( ~7 x8 M1 a                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)
: T3 A& R3 q( S$ ?& p                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
) v$ {: T# t1 H0 a, X! _                  RCC_PLLCmd(ENABLE);                                      (12)
6 F. F5 x4 E3 t) p2 Q                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)* X+ L$ _. s$ }0 ~; l
                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)( L5 {! P/ K( E- n
                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)' Q' R3 h2 r: h$ J2 X; ~
        }
6 h- Z4 h: O: b$ h; g; Z* b7 p

该用户从未签到

2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享4 u5 s0 i7 O- K: Y) P( X
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-23 17:57 , Processed in 0.187500 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表