找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

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

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

[复制链接]

169

主题

582

帖子

1242

积分

四级会员(40)

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

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

EDA365欢迎您!

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

x
STM32的时钟树
9 p% V# q& ?4 `" Y8 z         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。. V1 H8 V9 c( l8 N9 d
   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。+ Y2 `# Y( p( o" R+ q0 i
         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。+ u- L* I4 T1 c0 g; i
标号            图1标号释义& ~3 _9 r3 U+ l4 E2 J' K2 Q: a
1     内部低速振荡器(LSI,40Khz)0 I3 ^9 S5 k! |6 c# J
2     外部低速振荡器(LSE,32.768Khz)% P2 i7 J  c$ \9 f. X7 X
3    外部高速振荡器(HSE,3-25MHz)7 \! a! {+ T$ D2 x4 v
4    内部高速振荡器(HIS,8MHz)  u( @7 s% N0 k) }6 T& M* f
5    PLL输入选择位
. a' {+ M1 j0 d6    RTC时钟选择位
; P3 o( H4 Q3 p) D' R+ P# x* O1 M' B- E7    PLL1分频数寄存器, e; k5 Y! N. s
8    PLL1倍频寄存器
/ V: ^1 Z8 l/ Z( Y  c7 O9    系统时钟选择位
3 ]3 O5 D5 k3 [5 H10            USB分频寄存器  ~5 ], ]3 t. ~; y( ~8 ^- C
11            AHB分频寄存器
: L- k3 n3 Q" h! m/ Z1 X12            APB1分频寄存器: @1 @) l; o8 @
13            AHB总线6 @0 {9 P4 `) Y; Q* Z  L
14            APB1外设总线+ K4 [1 Q9 H0 g) g0 j: X; [& h4 ?' ]0 y' G
15            APB2分频寄存器) w8 S% s  p. f2 {$ r
16       APB2外设总线
6 X1 i8 r. _+ o1 x4 x! Q17            ADC预分频寄存器# N& s/ B' ^% R! Z+ {$ k5 f% J
18            ADC外设( F7 r2 L+ r; \  g
19            PLL2分频数寄存器
2 M' B, @2 ^- }, k  Q; N20            PLL2倍频寄存器
/ m, k1 j) {' k! ^! p- R( P21            PLL时钟源选择寄存器( x+ V0 f$ o+ t" S; W/ g9 N
22            独立看门狗设备
4 F8 v* \3 @. G23       RTC设备3 T* F$ N* ?) q' T$ B# _; l  `
STM32时钟树.jpg
0 L4 A* U  F2 j图1  STM32的时钟树, @. u- o* ]: L9 \8 u4 r- s
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:
9 J& E, r& N- h+ i( _8 t0 J1 v, U3——5——7——21——8——9——11——13+ i7 N* z+ z' k; |' V% W" i
对此条时钟路径做如下解析:
, z% p4 ^0 d1 u5 r5 t8 Q对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
: P3 d0 S" W; {对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);# c) a' P, V$ k& m, N- w
对于7,设置外部晶振的分频数(假设1分频);
  s! M- b: ~4 z. x# [1 C对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
( p5 n, H  m% K; ?对于8,设置PLL倍频数(假设9倍频);/ {+ T$ t, _  c2 p1 [3 [# b# `
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
$ Y2 U, f! I( D8 ?3 ?# i$ M对于11,设置AHB总线分频数(假设1分频);* [0 m& J" \- y; k2 b5 u6 |3 Y
对于13,时钟到达AHB总线;. e. c# P, a  m5 @/ n4 R
在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:
9 J  j8 }& i  m9 t3——5——7——21——8——9——11——15——16: k" j, H" K! F9 m3 Q& ]" B
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
- A! w) A# A: d. y- I对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
  Q% P" z6 b4 M对于7,设置外部晶振的分频数(假设1分频);
5 d9 A: L, p. G4 a( u" Q- t对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
8 _& n1 d8 A5 K: [2 N* x, `; l对于8,设置PLL倍频数(假设9倍频);
  P+ i5 x7 a$ W$ {对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
8 P" ^, y+ R+ p8 z) r对于11,设置AHB总线分频数(假设1分频);
3 S) F: X& E8 {. |* T对于15,设置APB2总线分频数(假设1分频);
2 V( i0 E$ B; I% O对于16,时钟到达APB2总线;5 |+ |- R0 ~6 H4 q' D, V
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):/ v% [0 H+ m( u5 N1 p- e$ x
1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
3 X* A8 }; `# Y/ j4 U0 h2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
$ f6 V0 u( x+ c8 Q+ N- e3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。, G+ x# i) E* ~. S4 i+ G! d
4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。4 K1 O- w0 j: H- r2 t
5)   时钟到达APB2总线外设。0 ~. \7 ?3 N2 O, v% o  @" @
因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:; v1 x* ~: A5 j2 c; n/ k5 R
void RCC_Configuration(void)
4 _; v2 p# z/ R7 y; H! c& J  V7 |{3 }/ y5 z6 H. t" f
        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
: Z. z% @6 r5 d0 F0 x, r2 _' c' s        RCC_DeInit();                                                             (2)& H! G# A  k6 R; W( \3 I
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)( y. g# O2 F2 j; k
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)4 F  R& H8 J$ n; O+ V; Y
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)/ B" s+ d# \; p
        {
7 o. Z2 Z' d" X+ B- `) [  v                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)! m' C+ e. [# `3 O& w
                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)
' N8 w! \: O$ R' o' i9 L1 o! B6 ?                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8); C# x3 f* L6 _" Z. k1 g; ~
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
, @2 _6 z! B+ H3 d- t                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)6 ?) |' E# n5 @. w* z! B2 d
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
; k( s$ W6 v6 I2 Y  x" F                  RCC_PLLCmd(ENABLE);                                      (12)
" V" d$ c7 i2 Z( x- r& ^* s0 u2 T, x* L                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)) r$ _9 [7 J+ A
                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
! W, h8 s; V% ~; r9 ^                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)8 r% P& a6 z+ s1 n) K1 B8 K
        }. T( l7 P* d/ b  A, l! N
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

245

主题

1028

帖子

1921

积分

四级会员(40)

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

积分
1921
2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
+ G8 w5 `3 x, M* Q: l5 E
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

巢课

技术风云榜

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

GMT+8, 2025-2-1 20:48 , Processed in 0.054585 second(s), 31 queries , Gzip On.

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

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

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