你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103时钟系统讲解

[复制链接]
攻城狮Melo 发布时间:2022-11-8 23:05
一、STM32F103时钟树
* n$ r; t- y8 f+ N+ `4 a  首先先放一张STM32参考手册中的一张时钟树,对照着来讲,如图所示:& ~4 \! ^& q4 k7 l( G) c" h* [

4 d) @/ u0 g$ ^( g. [) v. c 77f85107db1a437cb9dfeead7af43789.png
8 s3 Q) d! m5 V- s, D% g7 \1 z9 ]. O: D
% y4 e  {8 f& l! T1 V6 s! q  首先对图里出现的几个名词做个介绍:( R  H( e0 o' r$ ], ]
VS}CN8LOJ96ESYR%D_$OE6R.png * @: G; y* ]: n
1 T) a/ n( s8 b
+ G1 f% l9 h5 I' X1 @3 A* X
  为了更加清晰直观,再放上一张STM32CUBEMX里配置时钟系统的图:
* w( \5 b3 y3 y6 A) q
6 Q2 X- f% {. g9 {' n6 S d2e146e2ae1e4619809d6f78faa0ea59.png
! a4 O0 f- B7 E+ m( ?& q! A0 u
; W$ R: \8 |& O5 m: L2 C  首先先明确一点我们的STM32有HSE、HSI、LSE、LSI、PLL五个时钟源,接下来会对这五个时钟源进行介绍。
# a6 Q& }2 y0 j% C. R0 T) }, Q( ^+ F$ \! E
1.1 HSE、HSI、PLL、SYSCLK
$ ?; h3 z3 e8 q- w) ^: N" F
  我们想要配置的时钟是SYSCLK即系统时钟,我们一般说的STM32F103时钟72M就是指这个SYSCLK系统时钟,从图里可以看到,配置系统时钟的时钟来源主要有三个:
+ v( w; g+ l# W* h, ^6 t' i; K7 F+ [' W) D
8b3d31099fcf45bb99e8408b656d3a0b.png
1 u' Z  F' n$ X4 g: J9 W* u9 I# }1 ^! S/ L0 ~/ h! C
  分别是HSI、HSE、PLLCLK,我们配置系统时钟的来源可以是外部高速时钟、内部高速时钟和锁相环PLL出来的时钟信号,我们都知道在MCU没有超过最高时钟频率运行之前,时钟频率越高,系统运行更加稳定,故我们配置时钟时一般都是希望配置的时钟频率接近上限。' i3 o# l( d$ K- S
  在STM32F103芯片里HSI给定了是内部8M的高速时钟,HSE可以是从4~16M之间自己选择焊接任意频率的晶振,而PLL锁相环是可以将时钟频率倍频提高可以实现稳定且高频的时钟信号。我们先来看一下PLL锁相环的时钟线:
! l/ J2 `# |$ k$ ^* g5 ?" Z* {0 D7 @& R5 h9 a4 l( w6 M- v7 z
2ecd16f905bc4a81891b091239d1bf3e.png
: Y+ y7 Y8 Z: O( O+ P. s% D! e
- Q$ d8 N" }# _+ c3 i  PLL锁相环的输入可以是经过二分频的HSI也就是4M的内部时钟提供的信号,还有外部高速时钟HSE可以不分频或者二分频的信号,一般来说我们都会采用外部的时钟信号更加的稳定和准确,这里我们单片机外部焊接的是8M的晶振故我们选择PLL输入来源是HSE,在PLL内是经过*PLLMul(*9)来实现达到72M的频率,最后输出给到SYSCLK。, s& ~) X! w; B% m. }

& @" j+ h7 T+ l7 C( j) b1.2 LSE、LSI、RTC
; P1 o0 ~2 Q- Z1 \) N$ D3 f/ G  讲到这里HSE、HSI、PLL、SYSCLK相信大家都有了认识,接下来还有两个LSI和LSE有什么作用呢,我们看到STM32参考手册里有这样一段话:
/ @0 l. {0 Y! O3 X
0 ?& F1 K$ M! a) E1 i0 l7 N 0e1ea34bf28b4d6ba0c13067d53ddac0.png
; i6 B, x: I0 b. M
) H' C; k4 N# s& _/ Y1 }7 W  ?" C8 e9 u  我们的芯片内部低速时钟LSI是40khz的,用来驱动看门狗或者是RTC时钟的,外部的低速时钟是32.768khz可以用来驱动RTC,很遗憾我没有做过关于RTC的实验,故对实时时钟的解释不是很充分,没有特殊要求一般不会去用到,如图所示:
1 U/ f# O7 P, d# k- t* s" N, b
8 v. q+ q& t- |! \2 i& a8 H5 W: { 822a6f9f206d4ef3aa890c479f35dbb0.png
; o) j" y% M, G, j1 x$ M! O3 K; C. U' l7 i; V
1.3 重要提示
" r0 W3 ^6 T, j7 M8 i; G  上面介绍了五个时钟源,我们在不使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗,比如说我只用了一个HSE和PLL来配置SYSCLK,那么其他的时钟源可以不需要开启,以此降低功耗。& s9 v: ?4 U( a- ^8 y( x) O9 }% ~

8 f8 v% l1 u1 z2 P! {# X$ Q7 n1.4 HCLK、PCLK1、PCLK2) S$ E$ j( t( K
  配置完SYSCLK算是完成了时钟配置的一半,我们接着看时钟图后面,如图所示:
& d+ z6 t) H* ^0 Q7 g; I7 _  d) {
, Y/ [& h2 ^) y0 q8 N6 I 5651f43bde2e492c90dfb9f23a0d395d.png 9 h2 O! r$ c6 O  a; T) l" N

" e9 W7 x9 D5 b# T% _  SYSCLK系统时钟出来后可以看到会经过一个AHB预分频器,将分频后的信号给至HCLK高速外设时钟,STM32规定最大的时钟信号是72MHz,和我们配置的SYSCLK一致,一般都是将SYSCLK配置为最高的HCLK时钟频率之后预分频器分频系数给1,将SYSCLK和HCLK时钟信号频率配置最高,以此达到系统高稳定性高性能状态,HCLK出来的时钟信号会给至AHB总线、核心存储器、DMA:
1 j* A# m) z. w1 \
* I, n, |, ?6 n! h- s; A1 l f7c67056acce4ae6b3381cb8f768a4fe.png
8 s3 k/ E4 N1 i
1 a0 b' L0 E, b3 }  STM32还设置了两条外设时钟线,一条是PCLK1低速时钟,另一条是PCLK2高速时钟,PCLK1经过AHB1预分频器分频最高可达36M,PCLK2经过AHB2预分频器分频最高可达72M,如图所示:
1 X1 m3 O! p* Z1 N  d2 B
9 y: }+ M0 @2 S- M! @4 X5 n 2a34abc27940462e994b36a25b83c57b.png & W5 ^* }( J4 T9 d2 X# I$ X" _& i' r
9 d! ]1 h% [) s9 F0 I
  在外设中存在着比较特殊的比如定时器,如上图所示,在APB1/2分频完成后有对搭载的定时器TIMER进行了分频那么怎么确定应该是多少呢,可以在STM32参考手册中找到这样一段:
) S5 |) F  A0 x
" {4 h  z" X* {( b% t9 S; o. E e697b83e5c4d43a198d9c0168df8569f.png / }# z* a0 |! x% C, g8 B
$ I9 J6 L6 V- M! L
  为什么需要这么多外设的时钟呢,我们都知道在操作STM32外设之前都需要打开对应的外设时钟,比如我要操作GPIOA01输出高电平,我需要先打开GPIOA的外设时钟,才能对引脚进行操作,如下图所示是STM32F103各个外设时钟搭载的外设:7 R) Y6 `+ S5 X! j- I1 q
  AHB搭载了DMA1/2、SRAM、核心存储器等都在HCLK提供的时钟频率下运行,比如想要用DMA1就需要通过打开AHB下的DMA1时钟,时钟频率就是HCLK,才能使用DMA1。; Y6 w3 Y0 u5 B7 ^

4 y8 D6 j( a' j) v2 d 194daa2843a54fd782b2c90e06401903.png 3 K( i% t! n5 p1 c

5 n, ]6 u( E+ ?  A5 X: z; E$ y  APB2搭载了例如GPIOA~G、ADC等
4 u; M/ X# [" N) f
( K$ |7 {9 a5 L# c 6e178c0262b94cb8a93dd5d896f5ae93.png
! b: T- j- e7 u5 w( }
( P& m" @/ E4 D' ~* o' E  |5 u  APB1搭载了通用定时器、USART、CAN等外设; ?& h) u* r9 r2 u

7 c, c$ {$ n2 [ 61bb9fb180c74d2dbf0079bc8061e673.png 1 @0 G$ ^$ {& a, s( i1 O% e& t0 ?

. g* n* `/ a) P1.5 时钟树小结+ S# e8 G2 p3 ?" ^: O
  一条较为完整的时钟配置路线大致为:HSE–PLL–SYSCLK–AHB–HCLK–AHB1–PCLK1(/–AHB2–PCLK2),综上就是STM32配置时钟树的大部分内容,相信大家对时钟树的理解进一步加深,接下来我们讲怎么在标准库中配置我们的时钟系统。+ k' b  o6 A; ^+ V9 s

, [3 W) _+ O$ b& C, b5 Z二、程序配置(以之前新建的工程为例)
2 z& x: v$ B2 d- V  第一步打开我们的工程文件定位到startup文件夹,双击打开我们的启动文件,如图所示:
! T) _$ S6 y- K9 n1 Z5 W; F$ x. t2 V! ], Y9 J4 Z% w+ Z
c078b8b58699408f957e08da30672f4a.png 2 C2 o/ _( f  Q! n/ U

" l2 w. |3 U1 b) J$ o, r% _3 O  第二步我们知道STM32程序都是在启动文件里开始执行的,所以我们下拉代码找到程序运行的入口SystemInit,选中SystemInit鼠标右键单击Go To Definition…或者选中后按下快捷键F12进行跳转,如图所示:( U# @, d+ R! m* A: r

/ b2 O' A; b. _' l5 b 35d0948319044dfd83a92571bc8949d0.png + O( R! e8 f' g0 m( @5 @6 A

$ O# A" I. U0 N4 I2 F' w% {  B  第三步 SystemInit函数刚开始是初始化了很多与时钟相关的寄存器,将RCC时钟配置重置为默认的重置状态,往下看会找到一个SetSysClock()的函数,再次跳转,找到函数主体:- d0 y8 ]& r  S8 G3 d: P6 ?

+ G9 M4 |) t* ^7 y, C; t 0c39ddb35354468e918073257ab7643f.png , ?0 o( P- B7 X$ F2 G2 b

9 N) f7 P/ E3 W, S; c  第四步跳转后可以看到这里通过判断标识符的方式将会执行SetSysClockTo72()函数,我们设置了72M的系统时钟,可以点击宏定义标识符查看,根据需要可以选择不同的时钟频率,如下两图:" c1 O- g( @# T

: v1 c) t1 f" [+ M& I 13211d478bca4f5387d092e12099f3f1.png 1 N, ?- f0 n. Q# x7 @! B+ W* x" t
& l# r6 e/ n7 a0 I6 x
47d635e25e6145808327d5b94f289cb0.png
! p6 j4 q; ^* }6 v) k# U1 u  \0 u' m3 A! x. g( l' `. H
  第五步再次点击跳转SetSysClockTo72()函数,可以看到,我们进入了真正的配置系统时钟的地方,该函数起到设置“系统时钟频率”为72MHz,并配置“HCLK”、“PCLK2”和PCLK1预分压器的作用。整个系统时钟配置的过程是先启动外部晶振等待稳定然后设置好AHB,APB1,APB2,PLL相关的系数再启动PLL维持稳定后完成时钟配置,可以通过官方提供的注释看到,比较关键的一段如图:
, k: n' P- ^; A1 J3 B5 I
2 j$ E0 T% J3 M) W9 ?+ U bbcf4f2212d94df5be9998fbccea0178.png # T, ^( v3 D+ P& g0 [# T/ i
' E' s5 v7 c# @4 ]9 g8 @
  可以看到,HCLK配置为分频系数为1和SYSCLK频率相等,PCLK2分频系数也是1和HCLK频率相等,PCLK1分频系数为2是HCLK频率的二分频,但是注释却打了相等可能是注释打错了。
+ Q8 }6 y4 @6 @2 U  |  v2 T5 }
* y( D) ^" d6 A. g6 H6 i( R 35e64dd4d70c4b32911514a3b92b7704.png
# t3 Q3 z8 t# y  l1 n6 r1 ?
, d! ?1 [' }; a  这里是PLL锁相环的配置,需要留意的是RCC_CFGR_PLLMULL9这个参数,最后HSE出来的信号会乘上9提供给我们的SYSCLK信号。
4 T4 j7 W! J' L% a5 @8 U  P) ?- i  第六步到这里为止所有的分频系数参数都设置完毕,最后要等待PLL提供稳定的时钟信号,整个系统完成时钟配置,如图所示:
+ v, [/ u* g# N( |' w# [* I" D* i# S) m; P
4ea3c96935b04b7c8b246306f4a1172d.png   z5 Z6 G6 Q6 H) t& f
! Q3 d" g( N% Y0 o
  注:那我们通过程序查询比如HCLK的时钟,程序怎么知道HSE是多少呢,我们可以看到在stm32f10x.h里有一个HSE_VALUE的参数,这个参数定义的是我们使用的外部晶振的频率,这是8M,如图所示:
5 t. S( L8 E& ]( m! ^( }$ K: h1 k$ _; b
b57ce450ce334d52980f93988386d3b9.png ) Q7 p2 ^# Y5 X+ @8 B2 X  G
1 Q7 c) C9 }( ~8 |
三、小结
8 w+ \  E/ h) P. W  这一讲我们认识并强化了对系统时钟的概念和理解,对程序的配置上有了进一步的认识,大家可以在自己研读一下设置时钟的程序,这里程序讲的比较省略了关注点在时钟配置上了,下一讲会教大家如何运用keil5的DEBUG功能查询我们设置好的时钟频率究竟对不对。& _& D6 Y1 L; _( [9 k* i
————————————————
2 x. X, U5 Y3 c. S- M0 }0 v8 T版权声明:水水爱污污
" {+ ?1 [+ y; u2 F- R1 o" |- p  l) S3 B8 J* z  ?4 v& Z
1 d) Z( A9 V9 T+ Y
收藏 1 评论0 发布时间:2022-11-8 23:05

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版