找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

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

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

[复制链接]

169

主题

582

帖子

1242

积分

四级会员(40)

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

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

EDA365欢迎您!

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

x
STM32的时钟树
9 A7 j. y3 B+ E         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
2 i# H, o9 a+ s- S; U% w/ R" E7 {* P6 ^   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
% w5 `. J8 `; B7 ?  o1 d         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
0 j2 v# d: s0 z: \标号            图1标号释义
  F1 m8 e, m% L$ c( e  ~1     内部低速振荡器(LSI,40Khz)! n8 a7 Q) Y1 ]$ M
2     外部低速振荡器(LSE,32.768Khz)
6 a5 h9 y9 y0 j+ D* a( l' u3 T3    外部高速振荡器(HSE,3-25MHz); i  x  m4 F6 S" V' x2 k9 Z2 \
4    内部高速振荡器(HIS,8MHz)
' b* d2 h1 G8 J+ }  b5    PLL输入选择位
' w" h: N* c- `  c$ @" ~6    RTC时钟选择位/ G' `) Y  B2 x
7    PLL1分频数寄存器- K% z0 D6 \0 \% s* ~; v9 }3 D
8    PLL1倍频寄存器
' z( \' r, H& X4 ?; l* _9    系统时钟选择位' j& Q2 D4 w3 u0 s
10            USB分频寄存器! f0 ]) U- @# `: N) a% O
11            AHB分频寄存器. F4 |+ c9 k1 L
12            APB1分频寄存器
& i$ }- U# c4 Y13            AHB总线% ~( j+ a9 _+ m& h4 @/ M
14            APB1外设总线
' G5 R- w1 S" u7 h% f3 `  ~15            APB2分频寄存器- Q) T9 x2 s( V% n5 H$ v2 v
16       APB2外设总线( k( b/ }! I) S+ y8 f: D( D
17            ADC预分频寄存器8 [8 @/ o# V1 q# l7 X* N
18            ADC外设  {  o$ F* z5 k+ m
19            PLL2分频数寄存器
: k5 i, r5 X' ]5 r9 z20            PLL2倍频寄存器
1 V5 U. ^6 ?, B9 X: o21            PLL时钟源选择寄存器
; y* g. b3 m/ h9 G/ B2 E( u9 K22            独立看门狗设备( x4 U5 _. V! e6 U# X- Y
23       RTC设备
7 v- w5 f" I% l& D9 y: B4 hSTM32时钟树.jpg
' p( d9 R$ G' [. Z图1  STM32的时钟树8 J+ o  D* w# \: G
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:
* }4 w( u, [2 r3——5——7——21——8——9——11——13% [* x6 N  V$ K7 w
对此条时钟路径做如下解析:% S# h# ?( @' S4 N1 u& e3 W
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
# L- T( l  M! z+ n0 M6 s7 ]! `对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
6 D- p# \6 |3 E% V, r3 z对于7,设置外部晶振的分频数(假设1分频);2 d- j9 \0 u; {
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);* @# x6 w' a  I
对于8,设置PLL倍频数(假设9倍频);2 F9 H5 l& l; {# i
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
/ O' q, V% L; g6 y8 K  K  ?1 m* A对于11,设置AHB总线分频数(假设1分频);0 D, F6 Z! C9 o; C9 E
对于13,时钟到达AHB总线;
( D4 I! r9 s1 `% }( J9 d! {在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:1 I! I( _5 x) Z. f4 O: B. u1 t
3——5——7——21——8——9——11——15——16
3 [$ G  Y5 }" H! C对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
$ _( u& W2 H* K) U对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
2 b9 r6 I8 u. N! v, b对于7,设置外部晶振的分频数(假设1分频);; Y% D5 X4 }- T" D  l
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
5 B& ?- U7 ]: }对于8,设置PLL倍频数(假设9倍频);
7 H+ N# }8 T) r6 ?对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
% O# J/ n6 y& p对于11,设置AHB总线分频数(假设1分频);% Y* M: v" x2 N6 a6 ?$ D1 {
对于15,设置APB2总线分频数(假设1分频);  x; B* l1 p1 O, N; W+ A
对于16,时钟到达APB2总线;- [. ^( w+ n; v& |8 M) k1 r2 c- ]" F. _
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):0 C- `- Y+ C5 `* ]6 P
1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
) S, U* s" F4 g9 b2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。8 {+ U, j1 n; `
3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。
2 ~" x' F/ V% l) O6 ^( c# W1 O$ U4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。6 p- v* r) `( m# B1 c
5)   时钟到达APB2总线外设。
- l' k1 n5 \( _) O& m" ^因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:
; ]/ j! [! d0 i6 \$ w, _5 Wvoid RCC_Configuration(void)
& |' [# X1 j" `+ e" {, e* g! R6 L{. I: y( d8 L- f- W/ e- z  U
        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
0 ?6 x8 z( D( i        RCC_DeInit();                                                             (2)
; {/ _+ [3 `; ^7 K" n4 z+ ?        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)
* z1 b% u& d: l. g$ c        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)5 @6 J, z) F% f' I  L8 F1 D
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)$ ?8 v6 g. l1 |; |+ W  v
        {
, }' [* ~+ }) F- e4 Y) Z                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)' j, R; x; B4 U/ F
                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)
) j, O8 V6 W9 ~  _" Y% F3 i                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)
1 K) M& ~' z3 w: @                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
, _! f1 |# F6 [: y" k" W8 b3 t                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)
: W- |& r7 \3 z% W, o                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)6 ?4 y4 G& {+ u; i4 l2 }
                  RCC_PLLCmd(ENABLE);                                      (12), B7 H3 w* y) v
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)
5 G- Q$ t8 T5 ]5 d! {+ w9 E  h                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
! [' B0 ~( N8 d5 [% L7 m                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)
0 Z% Z8 b7 q# }' \0 v+ M        }
4 ~1 ~0 w0 b. z3 j  G$ a
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

245

主题

1028

帖子

1921

积分

四级会员(40)

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

积分
1921
2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享- h/ L$ C* B8 H% L5 e% A$ q( P
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

巢课

技术风云榜

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

GMT+8, 2025-3-6 21:41 , Processed in 0.054959 second(s), 32 queries , Gzip On.

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

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

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