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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
STM32的时钟树; `8 U5 m9 u( J, H6 K' N1 @& K
         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
# o# ^  B( {/ x" o3 s5 y( I   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
# R) \+ d! G/ B' f7 [1 i; ?# J         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。6 R  h: u$ a. F4 q9 j& V5 a7 O$ x* z8 q3 e
标号            图1标号释义
" D7 F4 Q- @% g, B! w7 b1     内部低速振荡器(LSI,40Khz)
/ O$ T! b/ p! c# k2     外部低速振荡器(LSE,32.768Khz)
! a  V& _! a0 w; y& N+ C) |3    外部高速振荡器(HSE,3-25MHz)1 e" q0 y& u7 R# W; ^3 F
4    内部高速振荡器(HIS,8MHz)2 B- _0 e0 Q# k# H. _' }
5    PLL输入选择位
& K) G8 Q6 i$ K& I& @6 y; J6    RTC时钟选择位
1 D1 g. b, w; `7    PLL1分频数寄存器
) Y, {2 v( c/ P# V0 ?8    PLL1倍频寄存器
( k  P" f: q: D* z2 i/ a- g, v9    系统时钟选择位
( y! D" i- t8 J- ?$ ?/ H) l$ [10            USB分频寄存器
9 Q& w) ^9 d/ Q" [9 r9 X11            AHB分频寄存器7 R) w/ n" ]4 _0 y3 ?" W
12            APB1分频寄存器
! ~9 n; ]% J$ [. r+ ~: g, c% `13            AHB总线) K# G& Q: o; j: g7 W6 c- G
14            APB1外设总线
8 R7 H1 l* r9 O, \9 J3 e15            APB2分频寄存器4 Z) g" I9 L% I7 K; @
16       APB2外设总线
' y+ W5 t" o" K# ^7 |17            ADC预分频寄存器
9 i5 ?. I( {  U* T18            ADC外设3 n7 W2 M5 o0 k
19            PLL2分频数寄存器
5 s6 E$ v7 A/ Q) P# ?; [7 W20            PLL2倍频寄存器
2 `3 O1 K0 v, y- p% v21            PLL时钟源选择寄存器
( s" S( u: h" ?! e22            独立看门狗设备
+ _' b2 ]: ]. Y: p1 O& ]% L23       RTC设备
$ z$ @4 h) P; e4 zSTM32时钟树.jpg
  g% U2 h1 M$ d% S6 o( q) m& p4 L* B图1  STM32的时钟树) K5 Y: T" o$ ^8 T8 A/ M# @. Z
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:
1 a6 l, J$ Y! Y5 @$ b3——5——7——21——8——9——11——13
5 q; O$ B( ^, ~( v) m! H6 F对此条时钟路径做如下解析:
9 T3 M( H' g) A对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
; S" P9 ^$ h/ k$ R$ q9 ]对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
. S% ]& w+ G  `* s0 p# J8 r( ]3 M对于7,设置外部晶振的分频数(假设1分频);
$ ]8 D5 N  b/ W对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
, d% {" \  n" {7 Q& g! g对于8,设置PLL倍频数(假设9倍频);
# h6 O- ?6 O/ @对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);* E+ T* O6 R! j. [  E! y& b
对于11,设置AHB总线分频数(假设1分频);
% u, c3 g7 \' i9 Z2 J* C对于13,时钟到达AHB总线;
* r  x- o' ~5 c7 r& P5 g4 X在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:' I4 _6 N4 F5 M! `9 Q- P. ~6 L9 e
3——5——7——21——8——9——11——15——16
8 J3 {% }6 W  Y5 |" {* t, i对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
# Q8 p2 J( Y2 |$ _1 f对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
! f+ m* j4 s# E对于7,设置外部晶振的分频数(假设1分频);) I; W$ S7 a6 L; w7 C
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
5 T9 X0 `. C* s8 L3 o1 `+ \, J对于8,设置PLL倍频数(假设9倍频);
5 [1 d) f) C2 n2 L9 {对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);/ C) T1 n% A5 _5 Z9 K* n+ Y. b
对于11,设置AHB总线分频数(假设1分频);2 C( u4 R6 o* b+ k
对于15,设置APB2总线分频数(假设1分频);3 ]% [0 c3 T3 u  z- q
对于16,时钟到达APB2总线;: S! q! N2 g3 Q& T7 Y; E: y
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):
) [% t* b* F- }1 w' _3 k1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
, [& T8 i" W1 F  p* d/ @2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。, J' J/ u) R! O- F7 t* ]
3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。
# ~# L1 ?" \! Y4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。
, j1 _5 [8 v' W: x; |5)   时钟到达APB2总线外设。4 [" F% R8 z( {+ l6 K% `" N3 r4 r* i8 O
因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:
. r- r/ n  J/ y; ivoid RCC_Configuration(void)  K5 [- Y1 T3 |+ {; J; G
{
8 f  d5 X  ]- p. D        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
( Q; s9 m- B% }* ~9 C* v        RCC_DeInit();                                                             (2)
3 r" A2 E; y, O# H* V" I: r5 Q! G        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)
. |+ Z+ D+ N$ w! `0 v1 s" F        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)
. W6 ?; T! P+ k7 G$ T        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)* E- [; }* ?5 a9 S) g
        {- i9 F8 Z# ?: M$ C6 a' ^
                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)
& ~& V! k! N. ]! N& Z! `                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)
, g2 l+ B, k* Q. {$ q& \                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)
/ {6 ^1 J6 x% Q0 \3 X* |                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
) A3 a% R% J3 u3 }! i2 y                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10): h2 U' W3 `0 r( g% W# E* \- c9 o- Y
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)6 g. C9 |% w4 ?7 e3 r
                  RCC_PLLCmd(ENABLE);                                      (12)' q' U8 x) `7 [* N1 I
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13); V/ }& Q! x; l: K
                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
/ R  Q/ M& d  r8 F' F; |                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)5 x$ e4 B6 d. `2 r  w$ o. b1 l
        }
" o" I2 t8 v* U# T

该用户从未签到

2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
3 k" V" j: w: g- y: Q! Y
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-13 12:30 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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