找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

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

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

[复制链接]

169

主题

582

帖子

1242

积分

四级会员(40)

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

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

EDA365欢迎您!

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

x
STM32的时钟树+ T- x; V  V4 I& [1 f
         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。
1 N3 L! a4 {4 u4 J; B   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
6 [: x5 ^6 I& i' k4 g$ D         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
% a* z5 R0 M; r标号            图1标号释义; Z! \2 M2 L3 ^, Y. O1 D
1     内部低速振荡器(LSI,40Khz)  V( h5 _( P1 z& O$ `- h& {# E
2     外部低速振荡器(LSE,32.768Khz)- u( [! x( J" C4 U' G
3    外部高速振荡器(HSE,3-25MHz)0 W& X( S$ B( K3 N
4    内部高速振荡器(HIS,8MHz)2 O5 q8 U& j# S1 y7 L1 o( I$ I
5    PLL输入选择位; V9 }' H0 e- E$ M4 j
6    RTC时钟选择位
# N% J$ U& O! g1 H7    PLL1分频数寄存器  P+ ]9 L% J4 w7 q$ x7 ~" G
8    PLL1倍频寄存器7 V2 ?5 a+ B/ k5 j3 _, Q4 w
9    系统时钟选择位
9 V$ J8 n) J( e10            USB分频寄存器
) }+ P# J. i# v( S8 n' Y$ b11            AHB分频寄存器
/ e/ g  K* J) i9 }3 s( [1 X12            APB1分频寄存器6 ~# N/ X/ K7 k) ?: k9 ~0 [
13            AHB总线
, N4 {0 G. }5 L* j9 ]14            APB1外设总线* Q7 B; r" K7 ]
15            APB2分频寄存器) ~6 U9 Q. q8 y1 h% d9 \
16       APB2外设总线
( M; u" y% u' {* N, h0 d17            ADC预分频寄存器" G. j% _' ^5 @& r& |
18            ADC外设
: X! [  a, j$ ~: ~% K19            PLL2分频数寄存器1 ]9 M  V" }8 _* r, {. ?. W
20            PLL2倍频寄存器. G+ H- Z6 s) O) z
21            PLL时钟源选择寄存器2 w9 C" p$ q) W4 L" ^, }1 s
22            独立看门狗设备2 G  q) T5 v. y1 h
23       RTC设备! g2 r+ z; @; {" P, f
STM32时钟树.jpg- y. x* q, v3 q" A3 r  e
图1  STM32的时钟树
5 o' H* j+ g, f  t# h. O" X; ]4 f* I   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:3 D7 E; e5 N( |- S" L
3——5——7——21——8——9——11——13
( G8 r& f( r* h, ]+ f" }对此条时钟路径做如下解析:
3 B: A$ F8 H+ g% x" K$ S6 E* H对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
4 Q; `% L7 D+ K$ F  x1 s对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
! I, g9 X* z5 A/ p$ B( i7 i2 t$ E" M对于7,设置外部晶振的分频数(假设1分频);/ N& A, o$ _7 Q5 O
对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);7 e  w% E0 m4 l
对于8,设置PLL倍频数(假设9倍频);
, D+ M* \9 ~0 p+ c对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
7 Y/ B! a& t' n对于11,设置AHB总线分频数(假设1分频);) Z" i. S$ q: a1 X. x+ q8 @1 K: `$ _
对于13,时钟到达AHB总线;
- }; d. A! {. c# M) y在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:; p& O% V# c% s' N! \* H+ v( K6 n
3——5——7——21——8——9——11——15——163 z) o. q, i& z: m3 I* |
对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
0 v3 k. ^. s" K5 {- {+ q6 Z7 u对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
0 m& T; u7 a$ m8 V. s对于7,设置外部晶振的分频数(假设1分频);
% {3 Z' D# b8 H, \, k; z- w对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);
0 u; J5 d7 r3 C对于8,设置PLL倍频数(假设9倍频);9 T/ X: W6 p6 ~6 {7 j% v- I
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);4 {: u" n: n- y. }9 n! z
对于11,设置AHB总线分频数(假设1分频);0 [: {& ?- {3 u5 k9 Y
对于15,设置APB2总线分频数(假设1分频);
2 E5 O  b# ^- p8 |4 D对于16,时钟到达APB2总线;5 h& m; y3 @- V, s
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):
- h' G+ H8 `; \9 |1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。
9 Q" Q- e& O- R, c2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
& W7 ~% s: \4 x. l# g% S& ?8 P3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。* N# E& _1 G2 ^7 y' z5 I: e
4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。& N. V$ L- r  \1 U. Y2 U8 E
5)   时钟到达APB2总线外设。
9 I/ L! `7 F! o5 g# `因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:; i) R; \! _7 i: B6 ?7 j
void RCC_Configuration(void)
/ R8 n' U$ q( w. G6 i{
' d% [" X2 @8 {% J# {* r1 _- T' c% p9 V        ErrorStatus HSEStartUpStatus;                                                                                                     (1)" o5 D  O) F# A
        RCC_DeInit();                                                             (2)' C5 C4 d; d3 d# l. ?( U% J9 E
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)
! c1 j. J* a& @# S( P# d        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)
7 ~$ a8 w9 l9 C7 S        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)0 d/ h5 E' p2 E: c" {) L8 p6 o( ?
        {
$ L2 K/ x/ k( `( s. ~3 A; ]) ~! K                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6): J- P* Q- k5 H& m# L5 Q
                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)5 ?) x4 ?- f3 C) f. j
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)
5 F  |- ^  K! Q7 ?6 @- U                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)
/ o) E3 q% f: p( L  ~5 L                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)
1 I6 F# w1 a9 d% ?+ k! e                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
( ^' _: m, w7 {) L3 {                  RCC_PLLCmd(ENABLE);                                      (12)
, v0 j5 w( l: e$ ^" D# F                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)
# S" r9 O# J7 f$ u* L! I                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)
) \! S" t9 ?+ Y' n5 z                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)
* W5 _7 z* ?1 L$ q( F' ?2 x/ |        }
3 j& p( I7 D1 |% m, v# I1 F9 i) r
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

245

主题

1028

帖子

1921

积分

四级会员(40)

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

积分
1921
2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享
. J+ f2 c* M4 o* a# l3 J
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

巢课

技术风云榜

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

GMT+8, 2024-11-9 09:38 , Processed in 0.056963 second(s), 31 queries , Gzip On.

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

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

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