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

STM32F103时钟系统讲解

[复制链接]
攻城狮Melo 发布时间:2022-11-8 23:05
一、STM32F103时钟树) x4 \& k$ M4 b+ J% r1 I" h
  首先先放一张STM32参考手册中的一张时钟树,对照着来讲,如图所示:. b3 \, Y- H; e! Q( J- S1 p/ N) _+ Q

: K8 P) Y* R* Z1 T 77f85107db1a437cb9dfeead7af43789.png 7 U3 R& D% J' ?& j6 j0 P* s
2 }% [- z% E! O' u
  首先对图里出现的几个名词做个介绍:
! ~6 P7 T/ j% d7 ]% D" A VS}CN8LOJ96ESYR%D_$OE6R.png % d, R% ?3 |; W6 U* G- k
5 ]! e5 @3 h% z, K- ^1 T8 {2 ^
+ O' U! C8 L& ^$ p0 m$ b0 s5 A* B7 B; u
  为了更加清晰直观,再放上一张STM32CUBEMX里配置时钟系统的图:, r1 W- M4 m; R: ~

4 g3 o* l3 i( ~" [; M$ L d2e146e2ae1e4619809d6f78faa0ea59.png
. ?% J$ \& l5 V+ u0 V4 I( P3 Y: |% r; I( r: S; f
  首先先明确一点我们的STM32有HSE、HSI、LSE、LSI、PLL五个时钟源,接下来会对这五个时钟源进行介绍。
" f* G# z, y" d: x: Z
3 U' s$ T. T0 Q% e- W* O2 K1.1 HSE、HSI、PLL、SYSCLK

$ H% d1 V2 H; z) a  我们想要配置的时钟是SYSCLK即系统时钟,我们一般说的STM32F103时钟72M就是指这个SYSCLK系统时钟,从图里可以看到,配置系统时钟的时钟来源主要有三个:
, k# |5 l1 f* C+ A; N# H) ^6 F* R# c6 l" N: T6 q, q
8b3d31099fcf45bb99e8408b656d3a0b.png
' {* Q' m5 C  Z$ t& C# R% p( {+ b
+ H7 E: K$ V1 a0 d( f  分别是HSI、HSE、PLLCLK,我们配置系统时钟的来源可以是外部高速时钟、内部高速时钟和锁相环PLL出来的时钟信号,我们都知道在MCU没有超过最高时钟频率运行之前,时钟频率越高,系统运行更加稳定,故我们配置时钟时一般都是希望配置的时钟频率接近上限。
5 B' v  {3 m# g% n  在STM32F103芯片里HSI给定了是内部8M的高速时钟,HSE可以是从4~16M之间自己选择焊接任意频率的晶振,而PLL锁相环是可以将时钟频率倍频提高可以实现稳定且高频的时钟信号。我们先来看一下PLL锁相环的时钟线:
# A8 a% v  h; F, E* t
1 F! q1 }& V  U2 f6 B1 w2 M! g# ~; S$ w 2ecd16f905bc4a81891b091239d1bf3e.png , P- u) x6 e/ [7 L% G
; n* D0 f3 a4 s) D7 }& D
  PLL锁相环的输入可以是经过二分频的HSI也就是4M的内部时钟提供的信号,还有外部高速时钟HSE可以不分频或者二分频的信号,一般来说我们都会采用外部的时钟信号更加的稳定和准确,这里我们单片机外部焊接的是8M的晶振故我们选择PLL输入来源是HSE,在PLL内是经过*PLLMul(*9)来实现达到72M的频率,最后输出给到SYSCLK。
6 Q( U  L2 x6 k4 ?8 Y% @" h
2 h* \" W9 ?1 {6 x5 X: j1.2 LSE、LSI、RTC
  t9 \. \! a( {& Z# r& W  讲到这里HSE、HSI、PLL、SYSCLK相信大家都有了认识,接下来还有两个LSI和LSE有什么作用呢,我们看到STM32参考手册里有这样一段话:
, V1 R8 P: j: ]% b9 ~2 J- z! z2 E) f+ F
0e1ea34bf28b4d6ba0c13067d53ddac0.png * T2 O/ D0 p, h% O! d

0 I! A9 j! d( `% Q  我们的芯片内部低速时钟LSI是40khz的,用来驱动看门狗或者是RTC时钟的,外部的低速时钟是32.768khz可以用来驱动RTC,很遗憾我没有做过关于RTC的实验,故对实时时钟的解释不是很充分,没有特殊要求一般不会去用到,如图所示:
2 K) x* g5 G/ n9 F1 M
0 y# y# r/ _6 E 822a6f9f206d4ef3aa890c479f35dbb0.png ; e: H* |$ V5 z/ R) L3 ^
/ `8 U) B: W+ I- o  H3 D" |
1.3 重要提示/ F1 G& T  S" R, h
  上面介绍了五个时钟源,我们在不使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗,比如说我只用了一个HSE和PLL来配置SYSCLK,那么其他的时钟源可以不需要开启,以此降低功耗。* J& Y/ Y7 v( e( }' [
6 \1 q: v' j6 }8 Z- y  V
1.4 HCLK、PCLK1、PCLK2# c' Q8 t. R4 x/ U5 B0 l
  配置完SYSCLK算是完成了时钟配置的一半,我们接着看时钟图后面,如图所示:
. c4 U9 ?# K7 `' e3 K: P' p; B
) h. c  V4 ]/ n! Y" w) V2 f 5651f43bde2e492c90dfb9f23a0d395d.png
/ L8 q- p* x+ _6 `2 u2 z- X1 B6 k6 B: G- b. f
  SYSCLK系统时钟出来后可以看到会经过一个AHB预分频器,将分频后的信号给至HCLK高速外设时钟,STM32规定最大的时钟信号是72MHz,和我们配置的SYSCLK一致,一般都是将SYSCLK配置为最高的HCLK时钟频率之后预分频器分频系数给1,将SYSCLK和HCLK时钟信号频率配置最高,以此达到系统高稳定性高性能状态,HCLK出来的时钟信号会给至AHB总线、核心存储器、DMA:# p# K- w- j+ [2 T  E3 d
! n3 C/ |, g% v& D2 F& h
f7c67056acce4ae6b3381cb8f768a4fe.png
& S5 A4 F& }2 s5 g; ]/ t3 I. T8 n2 j" X
  STM32还设置了两条外设时钟线,一条是PCLK1低速时钟,另一条是PCLK2高速时钟,PCLK1经过AHB1预分频器分频最高可达36M,PCLK2经过AHB2预分频器分频最高可达72M,如图所示:
* J) m' d6 ?- L! U" K, c, i0 q8 K5 U" s; v  r# {7 w& T% n: n8 P+ a
2a34abc27940462e994b36a25b83c57b.png
/ e2 C. u, J- {  x" D8 m& }9 Z" u2 O9 q3 s0 o
  在外设中存在着比较特殊的比如定时器,如上图所示,在APB1/2分频完成后有对搭载的定时器TIMER进行了分频那么怎么确定应该是多少呢,可以在STM32参考手册中找到这样一段:: C  @+ n- }" n- |
. B9 k* |# M. }: W
e697b83e5c4d43a198d9c0168df8569f.png ' H6 w1 U( Q- C5 T, n* g* B: ]
8 l8 K% c- a" s& E
  为什么需要这么多外设的时钟呢,我们都知道在操作STM32外设之前都需要打开对应的外设时钟,比如我要操作GPIOA01输出高电平,我需要先打开GPIOA的外设时钟,才能对引脚进行操作,如下图所示是STM32F103各个外设时钟搭载的外设:
- |. r2 ]) `  }* l9 m7 N  AHB搭载了DMA1/2、SRAM、核心存储器等都在HCLK提供的时钟频率下运行,比如想要用DMA1就需要通过打开AHB下的DMA1时钟,时钟频率就是HCLK,才能使用DMA1。
) c0 R# u5 e/ N8 f+ A3 f/ d6 t, S: Q$ s( u; z9 {
194daa2843a54fd782b2c90e06401903.png : i; Q4 c8 ?, b6 E) _

5 p) x5 V8 A! E4 S2 ?, A  APB2搭载了例如GPIOA~G、ADC等
) H' w7 u' E" C+ s7 s% \0 f( ]& p0 |8 D/ t6 I
6e178c0262b94cb8a93dd5d896f5ae93.png 2 B' I! w. n' z( p( r
: n) z0 i* W8 q) s' Q8 A# O/ o; G
  APB1搭载了通用定时器、USART、CAN等外设7 ^1 k2 J5 ^; q, X8 O1 x

6 f  Y0 P0 @! A/ T6 m 61bb9fb180c74d2dbf0079bc8061e673.png 9 ^2 r2 W/ K5 \
" E  J$ Y' ]0 b, x' n6 K2 G/ A" ?
1.5 时钟树小结
  W6 B8 X  N" L  一条较为完整的时钟配置路线大致为:HSE–PLL–SYSCLK–AHB–HCLK–AHB1–PCLK1(/–AHB2–PCLK2),综上就是STM32配置时钟树的大部分内容,相信大家对时钟树的理解进一步加深,接下来我们讲怎么在标准库中配置我们的时钟系统。! n% \* D" ~1 I* e: G
" |# e- o2 I$ v# P
二、程序配置(以之前新建的工程为例)
; Q9 D9 t6 ?1 Y' T$ _+ Y  第一步打开我们的工程文件定位到startup文件夹,双击打开我们的启动文件,如图所示:
  }) q/ H9 U& W- @: W7 |8 q2 K0 r: I) @& Q2 m/ G, j0 k/ n/ Q
c078b8b58699408f957e08da30672f4a.png   Q: a4 `! j& i$ x( r# d1 F( O

0 O: v+ ]7 g) T# b  z. F  第二步我们知道STM32程序都是在启动文件里开始执行的,所以我们下拉代码找到程序运行的入口SystemInit,选中SystemInit鼠标右键单击Go To Definition…或者选中后按下快捷键F12进行跳转,如图所示:
: l: l# _  ^: }4 g
  h6 i4 o- t$ k 35d0948319044dfd83a92571bc8949d0.png ! z$ `" D. O. p) a6 Z# y: H4 f/ l
. I5 K1 _2 n1 A, s6 ?
  第三步 SystemInit函数刚开始是初始化了很多与时钟相关的寄存器,将RCC时钟配置重置为默认的重置状态,往下看会找到一个SetSysClock()的函数,再次跳转,找到函数主体:
7 Y9 M* q" g7 d; [6 z1 c
0 X7 ~' U0 I+ R, q1 ^# s0 G 0c39ddb35354468e918073257ab7643f.png ) ^7 G6 F  r$ A# c9 w+ O- [8 b) s2 j
3 x. @1 ?7 A2 J+ R+ u+ m% O1 o
  第四步跳转后可以看到这里通过判断标识符的方式将会执行SetSysClockTo72()函数,我们设置了72M的系统时钟,可以点击宏定义标识符查看,根据需要可以选择不同的时钟频率,如下两图:
1 r0 O) b" `+ ~8 i* ~1 h' M0 }- |9 U) A: O6 n; e0 m8 F
13211d478bca4f5387d092e12099f3f1.png
7 T3 U0 R/ D) p  _3 F9 P9 G' |) s- U% y: N3 j+ \# K6 z
47d635e25e6145808327d5b94f289cb0.png
) z5 V' L& k$ J- _, z4 _# d7 i+ b( q, {/ @, x
  第五步再次点击跳转SetSysClockTo72()函数,可以看到,我们进入了真正的配置系统时钟的地方,该函数起到设置“系统时钟频率”为72MHz,并配置“HCLK”、“PCLK2”和PCLK1预分压器的作用。整个系统时钟配置的过程是先启动外部晶振等待稳定然后设置好AHB,APB1,APB2,PLL相关的系数再启动PLL维持稳定后完成时钟配置,可以通过官方提供的注释看到,比较关键的一段如图:
2 }; X6 q8 ~3 G( k! O
1 I4 h$ l  w  n: Q3 d( ~ bbcf4f2212d94df5be9998fbccea0178.png
  l; c+ j' f8 V1 g- U' e
! Y) U5 y1 G# ?8 `! T' ]  可以看到,HCLK配置为分频系数为1和SYSCLK频率相等,PCLK2分频系数也是1和HCLK频率相等,PCLK1分频系数为2是HCLK频率的二分频,但是注释却打了相等可能是注释打错了。
2 \. K$ M: \7 ]$ I* M" ~' G3 T& ]8 X
35e64dd4d70c4b32911514a3b92b7704.png
8 b6 m, r1 W; G: D* c8 b8 H3 ?
) s: H9 H1 T$ w; s) Q$ p; i  b  这里是PLL锁相环的配置,需要留意的是RCC_CFGR_PLLMULL9这个参数,最后HSE出来的信号会乘上9提供给我们的SYSCLK信号。
' {; q8 G3 _) o; H+ d* t5 `) J  第六步到这里为止所有的分频系数参数都设置完毕,最后要等待PLL提供稳定的时钟信号,整个系统完成时钟配置,如图所示:
- [2 u' v- d2 D: x) q
0 H+ T8 k/ s; ~0 k5 o 4ea3c96935b04b7c8b246306f4a1172d.png
+ G7 }. Q" |! d
3 i8 r" ]; b# U. R+ _5 O1 [: r  注:那我们通过程序查询比如HCLK的时钟,程序怎么知道HSE是多少呢,我们可以看到在stm32f10x.h里有一个HSE_VALUE的参数,这个参数定义的是我们使用的外部晶振的频率,这是8M,如图所示:
* p1 T: i! E) I1 r5 T  c# d4 f0 t7 M9 m5 a& y
b57ce450ce334d52980f93988386d3b9.png   a/ l" K' j9 d( k7 C7 L: `

" N7 D7 N& d" r$ H三、小结) k* T" U" h0 c) m0 |) s
  这一讲我们认识并强化了对系统时钟的概念和理解,对程序的配置上有了进一步的认识,大家可以在自己研读一下设置时钟的程序,这里程序讲的比较省略了关注点在时钟配置上了,下一讲会教大家如何运用keil5的DEBUG功能查询我们设置好的时钟频率究竟对不对。
. S- A! B& t. t# J& u————————————————
' X- G6 c5 P' J* k( M: ?  `版权声明:水水爱污污; x/ ^0 Q5 S# n% h) t/ S! @: Z

( P; J. `' [- n9 @8 p) r$ }' m
& g& q: H" P  K' {0 Y) i+ N
收藏 1 评论0 发布时间:2022-11-8 23:05

举报

0个回答

所属标签

相似分享

官网相关资源

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