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

STM32F103时钟系统讲解

[复制链接]
攻城狮Melo 发布时间:2022-11-8 23:05
一、STM32F103时钟树- z  [* _5 ]: I# n1 s+ j# X+ R" S7 p
  首先先放一张STM32参考手册中的一张时钟树,对照着来讲,如图所示:9 ~6 A; M$ [2 q2 S9 `% A$ k

3 q7 A# [& `; v9 x% Y' L 77f85107db1a437cb9dfeead7af43789.png " V. s" f$ v" _

2 `" s- o8 g. e* z, [. j) O  首先对图里出现的几个名词做个介绍:5 ]  r9 Z: m: E, T( ~$ o* e
VS}CN8LOJ96ESYR%D_$OE6R.png ; D, s% \, h9 H( r" \: [0 a
9 `1 @2 Y6 y* `% n
0 s, h4 p5 f3 }+ n' A: i
  为了更加清晰直观,再放上一张STM32CUBEMX里配置时钟系统的图:
# A, C! {$ C- m, e  d8 v
  m3 o9 s5 k5 e9 n# n8 t: M1 A d2e146e2ae1e4619809d6f78faa0ea59.png
& G! L4 T& [4 o$ U0 S/ |  A3 d! L" |$ r. ^3 \7 i+ H% d) V9 g( w0 X
  首先先明确一点我们的STM32有HSE、HSI、LSE、LSI、PLL五个时钟源,接下来会对这五个时钟源进行介绍。
! i' q+ f9 ?/ c& B! p% N
5 `: e, I; q( v. ~) n, |1.1 HSE、HSI、PLL、SYSCLK

3 K* Q- E& W7 q9 W& z# p7 w' b  我们想要配置的时钟是SYSCLK即系统时钟,我们一般说的STM32F103时钟72M就是指这个SYSCLK系统时钟,从图里可以看到,配置系统时钟的时钟来源主要有三个:
, t1 D9 S: O; W. u/ g' W5 b; n9 C/ S: `
8b3d31099fcf45bb99e8408b656d3a0b.png + V1 p( n4 w, G/ k
( Q9 k: W6 H6 M% I3 S4 k3 _8 B
  分别是HSI、HSE、PLLCLK,我们配置系统时钟的来源可以是外部高速时钟、内部高速时钟和锁相环PLL出来的时钟信号,我们都知道在MCU没有超过最高时钟频率运行之前,时钟频率越高,系统运行更加稳定,故我们配置时钟时一般都是希望配置的时钟频率接近上限。
( Z; `9 B& {2 m+ }  在STM32F103芯片里HSI给定了是内部8M的高速时钟,HSE可以是从4~16M之间自己选择焊接任意频率的晶振,而PLL锁相环是可以将时钟频率倍频提高可以实现稳定且高频的时钟信号。我们先来看一下PLL锁相环的时钟线:4 ~  J: R7 q3 X, C

3 t( z3 e/ g) |. T5 k 2ecd16f905bc4a81891b091239d1bf3e.png 7 G: `5 a) o- _( N) _4 U: Y3 @4 G# m

1 h' h7 k, X6 v. t3 @" p  PLL锁相环的输入可以是经过二分频的HSI也就是4M的内部时钟提供的信号,还有外部高速时钟HSE可以不分频或者二分频的信号,一般来说我们都会采用外部的时钟信号更加的稳定和准确,这里我们单片机外部焊接的是8M的晶振故我们选择PLL输入来源是HSE,在PLL内是经过*PLLMul(*9)来实现达到72M的频率,最后输出给到SYSCLK。
& B9 z) a, K( s- Q% Q5 A3 b& [1 u/ O) q+ S2 A7 O8 [: s4 L
1.2 LSE、LSI、RTC' \1 v* j. Y* `
  讲到这里HSE、HSI、PLL、SYSCLK相信大家都有了认识,接下来还有两个LSI和LSE有什么作用呢,我们看到STM32参考手册里有这样一段话:
) p. t8 k/ w8 |' F- i4 C
3 x" E  N% |3 a3 W3 ` 0e1ea34bf28b4d6ba0c13067d53ddac0.png
3 e6 W3 F9 B& d" w! k0 z, |! }. p: u5 h3 R, R1 m9 n; F! g( i
  我们的芯片内部低速时钟LSI是40khz的,用来驱动看门狗或者是RTC时钟的,外部的低速时钟是32.768khz可以用来驱动RTC,很遗憾我没有做过关于RTC的实验,故对实时时钟的解释不是很充分,没有特殊要求一般不会去用到,如图所示:
2 |# w$ K8 T1 }8 k; L- k# i
: n' F4 o9 D9 C; E- @1 y 822a6f9f206d4ef3aa890c479f35dbb0.png " w) H1 Z; S$ D3 z

: S/ W$ l3 H2 @% K1.3 重要提示% w" ?* N" y8 v* w" R; b; a
  上面介绍了五个时钟源,我们在不使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗,比如说我只用了一个HSE和PLL来配置SYSCLK,那么其他的时钟源可以不需要开启,以此降低功耗。4 R& a: i0 @) C

8 ]  q8 s" ^, @& q4 f1.4 HCLK、PCLK1、PCLK2
$ i1 \0 c! U/ q; [' g+ z  配置完SYSCLK算是完成了时钟配置的一半,我们接着看时钟图后面,如图所示:
6 ~3 a- Z+ d0 U: C) S; A) g0 \8 [2 h- M
5651f43bde2e492c90dfb9f23a0d395d.png % I6 K% u6 W9 C4 Y8 E& Y* n7 F

# i, c6 A, D# @2 ^9 Q  SYSCLK系统时钟出来后可以看到会经过一个AHB预分频器,将分频后的信号给至HCLK高速外设时钟,STM32规定最大的时钟信号是72MHz,和我们配置的SYSCLK一致,一般都是将SYSCLK配置为最高的HCLK时钟频率之后预分频器分频系数给1,将SYSCLK和HCLK时钟信号频率配置最高,以此达到系统高稳定性高性能状态,HCLK出来的时钟信号会给至AHB总线、核心存储器、DMA:) z" t; _6 r7 _4 l: T. G7 G
0 B: \9 R1 t6 s& W
f7c67056acce4ae6b3381cb8f768a4fe.png
# O+ f3 B% l5 Z' x6 n6 I; [. [# K( x5 L1 c2 c# H" h* @8 \
  STM32还设置了两条外设时钟线,一条是PCLK1低速时钟,另一条是PCLK2高速时钟,PCLK1经过AHB1预分频器分频最高可达36M,PCLK2经过AHB2预分频器分频最高可达72M,如图所示:
/ m/ K# C% @( I3 `1 m
6 [2 b' r" ^- @9 T% F$ b" e' z 2a34abc27940462e994b36a25b83c57b.png 3 m, m3 d* ^+ X- A
& F" W5 v4 R8 U1 L: T5 C
  在外设中存在着比较特殊的比如定时器,如上图所示,在APB1/2分频完成后有对搭载的定时器TIMER进行了分频那么怎么确定应该是多少呢,可以在STM32参考手册中找到这样一段:
6 s7 c7 ]3 W8 Q' O7 ]8 R% k0 x+ m8 k& d) }
e697b83e5c4d43a198d9c0168df8569f.png   g/ t: E7 ~$ o, Z
) p5 l4 n5 ^5 {+ ^
  为什么需要这么多外设的时钟呢,我们都知道在操作STM32外设之前都需要打开对应的外设时钟,比如我要操作GPIOA01输出高电平,我需要先打开GPIOA的外设时钟,才能对引脚进行操作,如下图所示是STM32F103各个外设时钟搭载的外设:) m$ K" h2 P) ?9 ~$ h3 R& v
  AHB搭载了DMA1/2、SRAM、核心存储器等都在HCLK提供的时钟频率下运行,比如想要用DMA1就需要通过打开AHB下的DMA1时钟,时钟频率就是HCLK,才能使用DMA1。# f* R, X" E9 L: _: n! e

* o2 ^% N( b! D 194daa2843a54fd782b2c90e06401903.png 2 e: A# n) a% X8 S4 q, o. o# m

; a2 J, T3 U5 a  APB2搭载了例如GPIOA~G、ADC等- U4 T0 J+ f& I5 o4 t" a  C; P
( I- `3 t% O& k+ a
6e178c0262b94cb8a93dd5d896f5ae93.png $ `; ~5 T0 K& p- \% H8 _
6 z' p3 L! D+ f5 x( o9 ?
  APB1搭载了通用定时器、USART、CAN等外设8 g$ m5 `5 r3 m0 T; h# s4 R) F* p- k
$ j' a' N+ }9 t1 I! j6 U' z
61bb9fb180c74d2dbf0079bc8061e673.png ( H) f( n5 O+ ?6 e9 s% W
% S/ h$ y# E) G, S9 W- D
1.5 时钟树小结
/ t1 N* ]2 ]0 H# o% @- r% ], z% r  一条较为完整的时钟配置路线大致为:HSE–PLL–SYSCLK–AHB–HCLK–AHB1–PCLK1(/–AHB2–PCLK2),综上就是STM32配置时钟树的大部分内容,相信大家对时钟树的理解进一步加深,接下来我们讲怎么在标准库中配置我们的时钟系统。; J. U# O4 b: t9 }. ?, |
) Q4 W* z4 G4 o1 }
二、程序配置(以之前新建的工程为例)0 B! |) R& p2 ~2 ?, x# Z
  第一步打开我们的工程文件定位到startup文件夹,双击打开我们的启动文件,如图所示:9 U3 n! V4 ?6 p% |# A, [. {/ B

) S" l* v+ t, b c078b8b58699408f957e08da30672f4a.png . p7 P: j- g. \5 }9 g( L# f

* X# L8 |5 E( I- o7 D% s  第二步我们知道STM32程序都是在启动文件里开始执行的,所以我们下拉代码找到程序运行的入口SystemInit,选中SystemInit鼠标右键单击Go To Definition…或者选中后按下快捷键F12进行跳转,如图所示:8 h0 N" C4 p; G0 `0 b& p" a

- ]+ G0 L4 B$ T' g% k 35d0948319044dfd83a92571bc8949d0.png
) P/ Q; j9 a$ y" `5 t. z+ N
  M* A& a! {+ n* x  第三步 SystemInit函数刚开始是初始化了很多与时钟相关的寄存器,将RCC时钟配置重置为默认的重置状态,往下看会找到一个SetSysClock()的函数,再次跳转,找到函数主体:
( t2 M! Y: W. b/ M. c
; G2 D1 P5 P) W  i- l# i  W4 b0 h 0c39ddb35354468e918073257ab7643f.png
7 N6 Y, C( j2 [3 z; W9 J: o$ K5 `2 [0 K
  第四步跳转后可以看到这里通过判断标识符的方式将会执行SetSysClockTo72()函数,我们设置了72M的系统时钟,可以点击宏定义标识符查看,根据需要可以选择不同的时钟频率,如下两图:
6 B& U7 k1 N' W7 i1 M3 A
* z3 `4 }& F3 s& i( q  i1 @" q8 i 13211d478bca4f5387d092e12099f3f1.png
% F' J5 S5 d% F- u* B
* \' C0 K" L: @/ e" {2 P8 N7 r- I 47d635e25e6145808327d5b94f289cb0.png 8 R/ p( ?) n* S9 R4 ^1 W( h% l

) }, C1 Y% P$ K; N6 K  第五步再次点击跳转SetSysClockTo72()函数,可以看到,我们进入了真正的配置系统时钟的地方,该函数起到设置“系统时钟频率”为72MHz,并配置“HCLK”、“PCLK2”和PCLK1预分压器的作用。整个系统时钟配置的过程是先启动外部晶振等待稳定然后设置好AHB,APB1,APB2,PLL相关的系数再启动PLL维持稳定后完成时钟配置,可以通过官方提供的注释看到,比较关键的一段如图:
/ Z1 d! l7 s) p/ Y
% ~5 n( N+ [5 [0 J1 Z bbcf4f2212d94df5be9998fbccea0178.png ) _  D- f8 |: D6 M( x0 Z6 L  z
5 l# P! i: N0 O5 v# D
  可以看到,HCLK配置为分频系数为1和SYSCLK频率相等,PCLK2分频系数也是1和HCLK频率相等,PCLK1分频系数为2是HCLK频率的二分频,但是注释却打了相等可能是注释打错了。3 X2 ]6 ?) Y% R

  W. y0 |7 ]: d/ Y; S8 w 35e64dd4d70c4b32911514a3b92b7704.png
5 H0 K1 K/ p3 [7 I! z; J5 U& Z9 D9 d
" w4 n6 C" f' |' t  这里是PLL锁相环的配置,需要留意的是RCC_CFGR_PLLMULL9这个参数,最后HSE出来的信号会乘上9提供给我们的SYSCLK信号。
+ a4 Q) x/ D( G1 S3 Z0 C6 ?  第六步到这里为止所有的分频系数参数都设置完毕,最后要等待PLL提供稳定的时钟信号,整个系统完成时钟配置,如图所示:: f; V% C- S/ F
/ P( I: ?! n" ?) n0 N
4ea3c96935b04b7c8b246306f4a1172d.png 0 P. T( w6 Q4 }0 W

" w& v: q0 g8 ]  注:那我们通过程序查询比如HCLK的时钟,程序怎么知道HSE是多少呢,我们可以看到在stm32f10x.h里有一个HSE_VALUE的参数,这个参数定义的是我们使用的外部晶振的频率,这是8M,如图所示:
+ S, W8 t  ]% V6 u; R
3 U& D8 y9 T6 N) ~. |6 o3 M b57ce450ce334d52980f93988386d3b9.png 2 R  {# `+ \& a0 N- h: i

; M3 s# D5 |2 f5 v: Q! D三、小结
0 H3 Z" o: L7 U, J+ {9 T, Y( r$ V  这一讲我们认识并强化了对系统时钟的概念和理解,对程序的配置上有了进一步的认识,大家可以在自己研读一下设置时钟的程序,这里程序讲的比较省略了关注点在时钟配置上了,下一讲会教大家如何运用keil5的DEBUG功能查询我们设置好的时钟频率究竟对不对。4 p. [+ {2 T( l0 d
————————————————
  N: c- b, R" i& I版权声明:水水爱污污: o; M* N+ \# I  e- w
1 k" `& ?1 e3 K1 F) \7 m

4 x; q# c, X8 w2 p
收藏 1 评论0 发布时间:2022-11-8 23:05

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版