找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

巢课
电巢直播8月计划
查看: 121|回复: 1
打印 上一主题 下一主题

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

[复制链接]

169

主题

582

帖子

1242

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

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

EDA365欢迎您!

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

x
STM32的时钟树; ]7 l! m6 Z/ u% c& J' d# w; i/ k
         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。3 [) ^$ t% [* D; C# h0 e- I
   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。7 s1 C: y* Q$ D9 w# O3 Y
         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。2 U; n( E! S0 O* X4 b
标号            图1标号释义
6 h1 l$ a! X$ l3 [! }1     内部低速振荡器(LSI,40Khz)
2 i  q# T3 Z8 d- n* t2     外部低速振荡器(LSE,32.768Khz)" U( U0 V  `" b1 U* F& G! ]
3    外部高速振荡器(HSE,3-25MHz)8 [; d) Z0 a$ M3 ]" I+ L- D! Z
4    内部高速振荡器(HIS,8MHz)
6 X' K0 m7 t+ u7 f. [6 j5    PLL输入选择位4 c! |! Q7 E6 @+ _1 ?5 B$ j4 z
6    RTC时钟选择位& u) k/ ]/ p. `+ v3 v# |$ r
7    PLL1分频数寄存器# o+ w/ e  M/ D2 l
8    PLL1倍频寄存器/ m5 s6 J1 {9 i# m1 ?
9    系统时钟选择位* W5 l+ O- J6 v0 i' Q; s
10            USB分频寄存器
) V% z5 ~. l1 i1 q9 ^; v: X11            AHB分频寄存器
/ L5 C1 r9 v8 G6 n+ R0 d12            APB1分频寄存器" |3 a4 R- W: P2 z8 u) t
13            AHB总线2 c3 F5 ]4 b; `
14            APB1外设总线8 h! ~! V, e, z# B4 @' C
15            APB2分频寄存器! B7 D7 B6 w$ \2 Y- M) q& X  {
16       APB2外设总线4 W* s1 g2 I) D. H* x6 k& J' m
17            ADC预分频寄存器
4 x0 U8 P' W3 `. G0 w$ `18            ADC外设
5 I4 r$ ]& z3 d- B19            PLL2分频数寄存器/ o( _& m7 [1 ^1 \5 c
20            PLL2倍频寄存器+ Q- s! N; Y" X4 d% x, f
21            PLL时钟源选择寄存器
, f' T! D+ d0 K5 O4 b22            独立看门狗设备
" u6 G# u5 v/ c- i- I/ F23       RTC设备. f! |( N7 t: o* V- P
STM32时钟树.jpg" N1 U1 s3 J5 }8 N3 h) a2 ?
图1  STM32的时钟树
' q* f8 P9 P- }3 P   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:7 f' C1 M& C& }, p4 z
3——5——7——21——8——9——11——136 z/ m4 U; r( l1 T0 j
对此条时钟路径做如下解析:
  u+ E8 z3 r  _对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;! @4 a& S4 u# z$ j
对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);5 w8 `6 x4 h2 }
对于7,设置外部晶振的分频数(假设1分频);7 Q2 [. y5 X0 @8 q0 R% {0 E2 l
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);; R2 j. ]$ {; i: g) K
对于8,设置PLL倍频数(假设9倍频);
2 t, j1 c! h6 C/ x# [+ v9 P对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
1 R& _2 N. p' Q6 Y) k对于11,设置AHB总线分频数(假设1分频);; T+ c  a2 j2 c3 D3 @5 P& I
对于13,时钟到达AHB总线;9 I; |! q- _$ p* R; H
在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:- X( o) S% l5 T. u. i; B0 n' J
3——5——7——21——8——9——11——15——16
0 X3 Y, f8 ]9 x对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
1 n3 O, M; t) C( Q对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
$ s" f# R! O" K  v( A. j: y  i对于7,设置外部晶振的分频数(假设1分频);" [" u; p* y% L8 M, _1 e& ]
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);( S% b3 T( p2 |' t
对于8,设置PLL倍频数(假设9倍频);
! A. `) y- {6 D: M8 ^# c对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
# o) F. J. g! f1 R* Q( w. |对于11,设置AHB总线分频数(假设1分频);
& u9 y8 U6 d  j( G; |0 y8 C" q对于15,设置APB2总线分频数(假设1分频);
$ v; b2 ]3 E. n对于16,时钟到达APB2总线;
" B$ E' J# T8 m4 q9 F( W; n- q  l现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):6 n$ I3 ]; C9 v6 L& d0 O
1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
" e# r, \  Y+ u4 A7 \7 K2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。+ H9 W. a5 {0 D9 p5 i- k9 o& ^3 \
3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。
+ {: Q( o7 s5 [0 N) F0 f, Q$ p* L4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。
4 \% u% E- y7 w. z* G. x5 T: q( G5)   时钟到达APB2总线外设。2 s) b' m1 p2 L" s# s
因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:6 Y( K# s. P4 ?  x( g  J# N) e3 I
void RCC_Configuration(void)
4 G$ S$ [& q2 |5 C5 w/ p{
7 y0 @. a$ o, L5 k. @3 t        ErrorStatus HSEStartUpStatus;                                                                                                     (1)  I) r# o, j# q7 u; `% l
        RCC_DeInit();                                                             (2)4 K* r) x2 A- K9 w3 o5 ^9 {$ D
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)
. s0 D0 r0 v8 G' V        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)
$ U0 s4 k$ i; S: T( U  D        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)
; N* r; i# R. j        {7 E) Y- f4 Y2 n6 q# m# T
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)  L- Z. p* W. h+ a: d
                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)( b4 M# z- F. a  f8 \
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)7 p3 B% {3 T% [& K
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
, V: i  {" V0 c0 \6 x- B                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)& ]& g" j% g' H  V3 y
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
/ L. T6 m3 s* \* i! i, ~* d                  RCC_PLLCmd(ENABLE);                                      (12)& F) Y2 Y  ]  K" Q, R
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)/ {1 k' d8 e6 m8 U1 ]4 b! Y* q  Y
                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
( \5 ^/ Y7 P2 e7 ~, R- G                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)+ Y4 a  Z$ |+ ^. d0 t# S- Z$ U% }
        }
0 W: h5 Y/ J# K- l& G( `
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

245

主题

1028

帖子

1921

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

积分
1921
2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
5 G: i$ w& T; F* l1 {) v. e
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

巢课

技术风云榜

关于我们|手机版|EDA365 ( 粤ICP备18020198号 )

GMT+8, 2024-11-9 00:36 , Processed in 0.066445 second(s), 31 queries , Gzip On.

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

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

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