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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
STM32的时钟树
% x) V6 S1 O* ~3 D7 x9 H; k         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。" }9 L8 k- p% t* f; A, p
   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
5 [/ B) q6 C4 m1 `) b9 f2 J. K6 w         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。  b( s* y0 K* w
标号            图1标号释义
. p6 }( X" v8 D2 q& V, V9 l. y$ P, c# S1     内部低速振荡器(LSI,40Khz)
9 ~4 b. I0 v4 f; q2     外部低速振荡器(LSE,32.768Khz)4 Z- L& G6 h0 P) {- `
3    外部高速振荡器(HSE,3-25MHz)6 j5 j+ G  @! }+ Q  m# D" v1 u
4    内部高速振荡器(HIS,8MHz)3 h  D6 \- Y+ b1 P7 }5 H
5    PLL输入选择位
. w8 A  o( o7 ]$ e! L+ q6    RTC时钟选择位$ Z  ~: A# K9 S! \0 H' s" D/ t8 G
7    PLL1分频数寄存器/ o& z* W- K) n( K
8    PLL1倍频寄存器% W0 i! E' a4 [! g
9    系统时钟选择位
$ @5 l* _3 {6 {$ L10            USB分频寄存器7 }0 s3 e- z1 U+ v7 G- A
11            AHB分频寄存器5 @" p( ~1 P5 ]/ y# e
12            APB1分频寄存器
) M0 v1 |3 `9 Z; D8 c' f& I! _" K13            AHB总线
* M0 p$ X3 _3 t8 N9 M1 F1 M5 G  C) n14            APB1外设总线
( V- r$ g6 @' h; Y  N15            APB2分频寄存器
" n6 Z& L8 p( l  U' x0 o$ p16       APB2外设总线# i7 k9 f# s: l5 E! g
17            ADC预分频寄存器" v7 p5 i; I: \0 k! t" }
18            ADC外设. {# D- _- J4 s. c0 W* `
19            PLL2分频数寄存器) V3 L/ z. C5 C% U3 e+ E2 x( ]
20            PLL2倍频寄存器& H- V+ U& U) z  O
21            PLL时钟源选择寄存器) p/ C% C2 ?8 G# J8 T4 s1 }2 m
22            独立看门狗设备
% E# P# m8 t, ]3 e% q/ t% ?23       RTC设备8 t# @# A; s! A) Y" Y
STM32时钟树.jpg* p. g/ M# q. @  r
图1  STM32的时钟树
, X5 V! t! m8 ^1 d   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:. ]; }" t! k3 B
3——5——7——21——8——9——11——136 e( k" i) u3 |% x( w
对此条时钟路径做如下解析:
8 j, B7 {* B) U& @7 ~) Z- j0 z6 |5 G对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
% X# S6 k/ }0 H! Y6 ?对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);, V9 J8 N$ `- R0 V, k% Z' v* R
对于7,设置外部晶振的分频数(假设1分频);
  z2 d. H6 Q) n+ R0 \4 L0 {4 Y对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);1 j8 n$ l) i7 d% M/ f/ X9 k, v% Y' e+ R
对于8,设置PLL倍频数(假设9倍频);' f8 X: _- F1 V* f9 J2 I
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
7 s, ^0 p- `4 z# s) M! z, U8 o6 d对于11,设置AHB总线分频数(假设1分频);1 u9 o, [9 x' I
对于13,时钟到达AHB总线;4 g% R" X- z5 K. o  ^) D9 @+ l
在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:4 ]& i" H+ u& k7 u* s
3——5——7——21——8——9——11——15——16
- i5 G: Y( I* ?  f% O0 W& O对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;  u0 R5 J' @2 Y& t
对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);/ g/ [1 t2 g8 J# N8 N. j
对于7,设置外部晶振的分频数(假设1分频);
4 `# _3 n  h: {对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
0 I2 b0 W# h! R& G  u对于8,设置PLL倍频数(假设9倍频);" p! k- n7 X% e/ m+ b7 p; F) A0 v
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
! Z7 B9 p; ]. h7 N对于11,设置AHB总线分频数(假设1分频);# s$ t( d3 A$ o
对于15,设置APB2总线分频数(假设1分频);
. _- O: _) l0 a8 E* b对于16,时钟到达APB2总线;* \7 t; ^) X3 c
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):
9 @9 c( d9 E! ]  _+ H1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。3 R# v0 ^  E5 V8 A- H
2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。4 s& K1 z6 z$ X
3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。8 s0 p) u1 K# L4 K1 T! ?$ r7 w
4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。
8 d( T! F* _  i/ U2 {: L6 b3 M5)   时钟到达APB2总线外设。
( U  A/ s9 L% s/ b$ K因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:6 u0 P9 h1 C' d) ~! b
void RCC_Configuration(void)! ^- f- D* @& Z9 K
{
. t  f' l) E3 Q' `( w0 ]3 a6 A        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
) J- _- i3 ^; Y/ P( O        RCC_DeInit();                                                             (2)+ N: |( f+ h- C' j; G% Q8 a
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)2 c7 g- ?3 C2 o
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)) S, a  W' h& {5 Z+ T5 }) ]% Q
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)8 ~5 \' R: O& N+ a
        {$ ^1 U9 f, U( @& R4 L; F
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)
+ u. E( N2 X" S, I# z( [" r                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)3 g5 F% X- p! b% }( D
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)( M6 }1 h& n# T% K, _7 V/ h
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
, E% H- O5 ]& {7 [( I. ?2 f0 q5 g5 L                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)& l, e* ^6 I7 ]4 L* b
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11), h* G2 N/ ?, M' Z
                  RCC_PLLCmd(ENABLE);                                      (12)5 `( Q" r/ O; W0 F7 l
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)
/ b& @2 @5 ?2 s4 e3 |* C/ ]) U8 U  w                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
1 \7 V; b( \7 x5 x* N/ F! ?                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)2 x+ G' Q0 T8 p6 O
        }
( T, ?" `7 |; b3 f0 j3 A

该用户从未签到

2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
/ q# d8 U& ?9 ~+ G% i* x7 s
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-15 10:14 , Processed in 0.093750 second(s), 23 queries , Gzip On.

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

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

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