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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
STM32的时钟树
4 x0 ~2 Z# h+ p/ P; ^         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
7 M% L$ S; O6 P+ t   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。7 U, z) h6 q: b- Q0 J
         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。  @. w7 m) c9 o- ?! K8 ^9 ?% F
标号            图1标号释义
( W0 O3 O3 y, M( c4 a! M$ R1     内部低速振荡器(LSI,40Khz); K5 [& n" ?+ @
2     外部低速振荡器(LSE,32.768Khz)9 k' n( u5 ^* J- b: \
3    外部高速振荡器(HSE,3-25MHz)3 u; C: y" Y. M0 @
4    内部高速振荡器(HIS,8MHz)
/ ?$ K: j: z3 x* p3 x' \2 w1 _5    PLL输入选择位+ y; t0 N* v8 G  U/ b& S
6    RTC时钟选择位% H+ I: O" F& G6 Z
7    PLL1分频数寄存器
  z' Y$ g, W! Z; W5 P0 X/ T8    PLL1倍频寄存器
, w/ {5 q) `7 m, n. Z$ o) E9    系统时钟选择位
, n! X) U6 H9 u: |! _8 I+ E10            USB分频寄存器
3 f) y3 j0 P4 Z- e- H, |11            AHB分频寄存器: V; D; Q  {7 k8 X8 V: m* G" q
12            APB1分频寄存器
  h# r- @1 @- E13            AHB总线
8 a% e( W+ `$ U7 }' R8 X14            APB1外设总线
# u) n7 \3 o+ `7 D& L/ Y& M15            APB2分频寄存器
+ |6 G/ s( H, a$ g% I/ ]0 J16       APB2外设总线  F. C5 `  C7 `: G- d
17            ADC预分频寄存器7 f: y- x& ~0 s$ ]( t
18            ADC外设. c5 B  {% M) t( R% k
19            PLL2分频数寄存器
0 x$ A3 _, U( k! f, s, Z8 D$ C* @20            PLL2倍频寄存器
, P3 @$ [: V8 v4 ?21            PLL时钟源选择寄存器, ~1 h* ]5 {1 |1 Q2 W1 ^& O; M. I
22            独立看门狗设备: {; D- W" H* [- q& q; N+ G9 @* e
23       RTC设备9 X, `+ g% D7 `  a$ ?7 u( g! U( T
STM32时钟树.jpg
3 s4 O: R; ]/ V; J- ]5 m0 H图1  STM32的时钟树2 [' Q& d: D4 E# U* z# y4 L
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:
, m3 v; z9 ]: S" n1 y3——5——7——21——8——9——11——13
) Q% g$ I( a0 i9 M对此条时钟路径做如下解析:
  i/ t% [- }  h  N对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;: I' o/ V$ b" D1 N7 }! X. z7 ?
对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
' t! n' k$ e% M对于7,设置外部晶振的分频数(假设1分频);7 K$ O- l0 b3 y5 e# A8 Y( p
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
* B& N- s9 M4 X1 U% `+ X4 }对于8,设置PLL倍频数(假设9倍频);
5 M% [2 \  |! s& T; k- ~! l对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
; L( |# w% G: W; u7 o+ d- k/ Y对于11,设置AHB总线分频数(假设1分频);
3 n3 b5 G+ a3 q) m$ a8 d- K* \对于13,时钟到达AHB总线;( L4 R" y0 F: K
在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:
9 q  m% l! X$ Y3——5——7——21——8——9——11——15——16. C$ A; H0 d" p. }/ Z
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
) K& f  D; {7 t! T) m5 Z7 I对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);6 H1 y: Z" g! Q2 z5 G* P* E
对于7,设置外部晶振的分频数(假设1分频);4 A/ K" n6 C6 I  u
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);( A' Z+ x8 R7 ~, K( A
对于8,设置PLL倍频数(假设9倍频);
: z% I/ ^( T0 V) W1 ^# E5 z对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);. M7 K. ?! M7 `6 V1 x' }2 m3 B
对于11,设置AHB总线分频数(假设1分频);
. H' _2 \, r+ U1 w: F& U( U对于15,设置APB2总线分频数(假设1分频);/ V1 |- g- W$ O2 {
对于16,时钟到达APB2总线;! U  c8 q: ^/ R' p7 X
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):
* C8 {1 L  J9 P4 r1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
* e% a3 ^2 [  m2 P9 W2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
/ Y0 A# F- k+ l6 B3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。
0 |( b+ d$ o. N' n! z4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。
$ d# v: c+ Q9 u1 z  j1 j# G5)   时钟到达APB2总线外设。0 t  a9 C' D7 S$ u
因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:
' N+ `$ H' U% dvoid RCC_Configuration(void)$ N( L: `4 |1 _. d6 `
{
" q1 k8 x- k* Z        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
+ D8 V7 d# S- `        RCC_DeInit();                                                             (2)' g7 h6 g, D) e+ u
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)- D5 r/ v) X/ i' ?% U8 F( C
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)
8 `4 t$ o4 v7 N, @+ g; X- N        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)( t- m8 B- v$ N. w: n4 \: Q0 [, f" f
        {. K6 L2 E; j$ G8 _' ~1 H! {3 P
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)
' Y  i1 _, V  X  G0 K* S, N2 {                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)! X# B" H# L: {
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)
' D4 a9 L6 n- h4 W3 U6 v& \1 D                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)  p, c/ t+ {3 r4 ]
                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)
" [1 ^! H) V% g+ G                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
& }% m; F) d- B                  RCC_PLLCmd(ENABLE);                                      (12)
3 I1 J$ P# [7 J6 D, {& |                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)' `% W. F% _0 `1 V# i* T
                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
8 J6 N3 ?. s7 s! W: N0 c                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)
- |" L, B$ C$ I* n* ~3 n        }+ k5 A  w! ~" K' V+ B% k

该用户从未签到

2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
3 t: o; p" X9 r. O
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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