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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
STM32的时钟树
( _9 D8 D. z; q) q         对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。这问题有个关键字叫:时钟树。2 Z( J! K4 |+ l9 Q# L+ ]
   众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运 作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端8位单片机诸如 51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状 态(假设单片机处于正常工作的状态)。比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固 定的,用户无法将此时钟速率更改,除非更换晶振。
: O9 y( N9 m0 M+ f. C' D! @, I         而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。* b: h! K/ _8 K* A
标号            图1标号释义( N9 H4 G, [8 [# J1 n. y, @
1     内部低速振荡器(LSI,40Khz)+ q; [; \+ h' _& O/ j
2     外部低速振荡器(LSE,32.768Khz)) Q$ e- `$ V5 s$ {  a) w: D
3    外部高速振荡器(HSE,3-25MHz): Y! N, f  I$ S; ~7 Y2 k
4    内部高速振荡器(HIS,8MHz)
4 C, ~8 n* B) E( v5    PLL输入选择位
5 m9 S% H! ~1 h! n$ ]) W6 u0 Z6    RTC时钟选择位
% B! v2 }( N; k5 Y0 l: [% v7    PLL1分频数寄存器
% p1 K, f1 t$ F8 V8    PLL1倍频寄存器( F# U& J3 J: c  {" c
9    系统时钟选择位
. b  s8 i$ q  T. O' b9 y10            USB分频寄存器! i( q, G0 r8 U2 D) E& |( V' G
11            AHB分频寄存器4 j0 f: E3 h+ m6 |( p$ r$ U
12            APB1分频寄存器, p) @5 x* r. T" b5 D
13            AHB总线
% n# B: A; \! S) v6 x7 t; S6 i14            APB1外设总线& ^0 }" G' N6 R+ H% r6 h6 X1 x
15            APB2分频寄存器
& V. I# n8 w' Q& h3 t* {8 m' W16       APB2外设总线
1 @4 X* Z5 J* N5 y7 U/ u& m17            ADC预分频寄存器
, I! z2 M  P7 @+ r! m, W18            ADC外设
; N, @7 T" k4 ]0 M1 O6 C19            PLL2分频数寄存器+ f9 z/ P$ u: q* s( m8 o2 }5 ~
20            PLL2倍频寄存器. F6 G% W& D  I6 l
21            PLL时钟源选择寄存器. w# [+ e3 U7 e' C# U7 Y
22            独立看门狗设备
. E& f: B  u) R$ g' E: O0 ~23       RTC设备
" h2 U. t. @  Q) N; v3 Q9 G! @STM32时钟树.jpg, a5 D( Q8 `( H( J( a6 y
图1  STM32的时钟树' ~7 E8 D' }5 y2 Q/ ^
   在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部8MHz晶振作为STM32的时钟输入源(这也是最常见的一种做法),则这个 8MHz便是“主干”,而“分支”很显然是最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”:1 U+ F% u1 M2 r8 Q* r  S. z
3——5——7——21——8——9——11——13
8 j9 k" T2 D. V& U) r对此条时钟路径做如下解析:
( z" Q$ ?' {4 F对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;. o; R, y0 b" W
对于5,通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);  H: O) K9 O" V2 Y* c. n/ W
对于7,设置外部晶振的分频数(假设1分频);
9 l: ?$ t# {4 B对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);% s4 |" S  \' V; u! }+ x) o
对于8,设置PLL倍频数(假设9倍频);
: l0 K, g; }0 v" E" ^- S, c对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
7 o0 P) B6 E7 Q; s: t; c- I3 V对于11,设置AHB总线分频数(假设1分频);1 a8 n2 M, Y; X% _" l+ ^4 }' m( H- s3 Y, \
对于13,时钟到达AHB总线;
6 b# N8 H( @2 p, M) {在上一章节中所介绍的GPIO外设属于APB2设备,即GPIO的时钟来源于APB2总线,同样在图1中也可以寻获GPIO外设的时钟轨迹:) Q: v) W8 |* J# M7 ]" t  f' q
3——5——7——21——8——9——11——15——16
2 w6 c) T7 |1 Q4 s& K* c! m对于3,首先是外部的3-25MHz(前文已假设为8MHz)输入;
$ ^/ M1 r( R) a  C1 V/ e2 R' b. J对于5, 通过PLL选择位预先选择后续PLL分支的输入时钟(假设选择外部晶振);
+ Q% x7 |3 q8 `+ B" p9 ?对于7,设置外部晶振的分频数(假设1分频);
# d+ N$ u! }3 t0 X对于21,选择PLL倍频的时钟源(假设选择经过分频后的外部晶振时钟);: m3 O- u' i' D: ]* T
对于8,设置PLL倍频数(假设9倍频);* L! }8 ^1 T. Q+ V; V& u, d9 _
对于9,选择系统时钟源(假设选择经过PLL倍频所输出的时钟);
$ w; U# v) {# G1 M对于11,设置AHB总线分频数(假设1分频);+ O9 i7 r9 x8 ?; \7 C3 v- y9 ~: B  z
对于15,设置APB2总线分频数(假设1分频);& a7 c1 ~9 x5 L- d& O
对于16,时钟到达APB2总线;; {' u8 F8 \$ Y- @# P3 l/ \7 a/ ~% Q
现在来计算一下GPIO设备的最大驱动时钟速率(各个条件已在上述要点中假设):
9 l0 t6 q, D% w' Z: V1)   由3所知晶振输入为8MHz,由5——21知PLL的时钟源为经过分频后的外部晶振时钟,并且此分频数为1分频,因此首先得出PLL的时钟源为:8MHz / 1 = 8MHz。. g' a, s. u$ g" s; E' ^$ ^
2)   由8、9知PLL倍频数为9,且将PLL倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz * 9 = 72MHz。
2 E1 Y, i5 f* w2 q. ~5 P6 S$ x3)   时钟到达AHB预分频器,由11知时钟经过AHB预分频器之后的速率仍为72MHz。/ R5 _% k0 _9 ^3 |5 p9 [
4)   时钟到达APB2预分频器,由15经过APB2预分频器后速率仍为72MHz。
% \" N) v' J: ?/ {5)   时钟到达APB2总线外设。
* T3 p7 \# a7 c' y: ]6 i因此STM32的APB2总线外设,所能达到的最大速率为72MHz。依据以上方法读者可以搜寻出APB1总线外设时钟、RTC外设时钟、独立看门狗等外设时钟的来龙去脉。接下来从程序的角度分析时钟树的设置,程序清单如下:6 K; b+ t0 }0 w# a
void RCC_Configuration(void)
/ I* l3 r# O/ F9 t( d, B$ X{  j; x0 k! A6 |' _" B- }
        ErrorStatus HSEStartUpStatus;                                                                                                     (1)
( u& g6 _$ ~- {+ g% G        RCC_DeInit();                                                             (2)6 B0 J- H( \. V6 V% {# M3 v
        RCC_HSEConfig(RCC_HSE_ON);                                                                                                   (3)# E/ E* j4 g$ W
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                                                                     (4)) G3 x' O/ d0 B' Z2 E4 H
        if(HSEStartUpStatus == SUCCESS)                                                                                                (5)
: ^0 F& ~+ j$ x- t! ^# R+ v        {
0 z% e" \; a  C+ f                   RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                              (6)
: I/ W2 `8 E! e  P1 c                     RCC_PCLK2Config(RCC_HCLK_Div1);                                                                               (7)) ?" U' x5 h/ k! ?, Y7 l) R1 n* A' Q* W2 h
                     RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                (8)' S/ Z' u/ H3 \' C* R5 S
                    FLASH_SetLatency(FLASH_Latency_2);                                                                             (9)+ ]6 k) S' R1 J6 Y
                    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);                                      (10)0 A; z% K0 z5 y
                  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                                         (11)
* D2 t( N/ ~5 U                  RCC_PLLCmd(ENABLE);                                      (12)6 g& X8 H: U% R  @2 E
                  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                                       (13)
+ ]" |, ?' L: p                  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                               (14)0 k: w' O8 L: S' l  [, M/ [& G5 H2 ]
                  while(RCC_GetSYSCLKSource() != 0x08);                                                                               (15)" d  w( p( h% [9 E% e/ D9 C- m6 R
        }& t) g6 N  G5 y: {

该用户从未签到

2#
发表于 2016-6-4 15:48 | 只看该作者
学习中,谢谢分享4 A4 q& Z7 O% o8 U+ B' f: x
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-30 16:26 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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