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

【经验分享】STM32F10x从零开始配置时钟

[复制链接]
STMCU小助手 发布时间:2021-11-30 22:16
实际上,对于STM32F10x系列的芯片,如果使用库函数方式开发,芯片的时钟初始化函数已经写好,并且在启动文件(例如startup_stm32f10x_hd.s)中被自动调用,在进入main函数之前,系统以及外设时钟均配置完成,main程序中不需要对时钟再进行任何配置,直接编写应用程序即可。但是作为一个底层驱动玩家必须要打破砂锅问到底,看看STM32F10x系列芯片的时钟系统到底是怎么样的以及如何配置时钟,下文将着重分析STM32F10x的时钟系统以及用寄存器方式从零开始一步一步配置时钟。/ E& X/ X4 e9 f- b, P* t

# U" a$ H' Z3 m2 o$ P, j9 @5 b" \一、开发环境
3 M: m% P; E& ?+ q, Z  [9 wMDK版本:V5.28
- o8 D% H; s9 Z$ t6 Y2 z" o3 z单片机:STM32F103RCT6
7 p" X! t/ R: {; v二、时钟树剖析# A  n5 b( f9 o, q6 i# y/ c
5 u3 p0 |( s1 G) `. G# H
5}7)N_$J[]~[E6]{CR@H)[Q.png

- ^8 i7 k4 B1 J0 ^- d
$ s- k, J( v' x. N4 \/ O$ z& ^上图就是STM32F10x的时钟树,看着十分复杂,或许有人会问,为什么STM32要把时钟设计的这么复杂?这是因为STM32的外设很多,而且不同的外设需要的时钟是不一样的,例如USB时钟一般需要48MHz,RTC时钟一般是32.768K,APB2总线上的外设最大不超过72MHz,APB1总线外设最大不超过36MHz,如何同时满足这些时钟要求呢?显然如果只设计一种时钟是不可以的,于是就有了上图中复杂的时钟系统。下面我们就来分析下上图的时钟系统。
" _8 O  Q; R" s8 V3 p) p6 q
, m/ P" R2 o/ L; w( O- I首先可以把上图的时钟树划分为以下几个部分:7 i# Z; w8 C' `( \  @3 R2 T! W; [

; h7 s1 }* G" g  z& }
6KXC8$)[K}1`$~AGTTMA(G9.png

# }) G1 u3 V0 P* u; f& }0 I6 L' B+ P* D% b6 M+ |& j
_T]8Z)V%2VIEX0BYS2831MD.png

. T/ g* o  m, H- y, D' P. x/ _: |  I; n3 A) g" {
基础时钟介绍:
* Z5 \) x$ f  W. u
5 h0 Z6 t2 S0 c; f* h
$SEZ~2)7W9YS)29YIGNQ`AE.png

- x0 X9 ~. J, v& @2 `* o, u- R+ p. g1 j" D6 f- n" y
基础时钟并不是官方提出的概念,是我个人的习惯叫法,它主要指的是HSE、LSE、HSI、LSI这四种时钟源,其主要作用如上图所示。& w. d( `+ L( h8 A1 H9 e
( ^, Q7 w( Q  E1 O9 L# ^2 m- |' e! J
系统时钟的产生:9 {# w7 @7 I2 E& S. y+ \+ M- p

' R. ]2 d" K7 z* ~8 g0 r# O) D4 r
ZXIP7BFKM02TZ%`[2YG_XQN.png

4 a% e7 f/ a) m7 r
( |: |9 ?) K8 p! q, v) \. B系统时钟的产生有三种方式:1>HSI内部高速时钟,一般为8MHz。 2>HSE外部高速时钟,一般为8MHz晶振。 3>PLL电路,输出频率可任意配置。其中HSI和HSE都属于基础时钟,如果使用PLL时钟作为系统时钟,PLL电路的基准输入必须是HSE或者HSI。* N4 {4 A& v$ g3 A& L* p( ~
如果直接使用基础时钟作为系统时钟,那么系统时钟最大频率≤HSE/HSI 如果使用PLL输出时钟作为系统时钟,那么系统时钟最大频率≤72MHz  i' ?0 ?6 \4 c. P. M
7 P5 c8 G1 D) m9 F1 ?3 a. S
下面就以定时器为例说明上述各个时钟之间的供需关系:
: @' p% m/ A2 c8 c7 a' Z$ m  X1 d
如果需要使用定时器,那么首先需要开启定时器的时钟,而定时器属于外设,因此需要系统时钟提供时钟给这个外设,对于系统时钟,有两种方式提供,一种是由基础时钟(内部或外部基础时钟源)直接提供,缺点是无法产生更高的频率,时钟源是多高的频率,系统时钟最大不会超过这个频率;第二种是由PLL电路提供,优点是能够产生各种高频稳定的时钟频率,但是也需要基础时钟提供基准信号,且一般情况下STM32F10x系列PLL输出最大不超过72MHz。" y+ |  c3 H2 Z3 M# X
一般来说除RTC外所有的外设时钟(TIM、GPIO、DMA、USART、USB等等)必须由系统时钟提供,但某些特殊外设需要另当别论(以太网、I2S设备等)! e7 u! {, l) R
( T/ d2 ^, f0 n' r
在STM32时钟树中,还有很多的分频器和倍频器,通过这些分频和倍频器就能产生各种需要的频率,但是只有PLL电路才可以倍频,即产生高于输入频率的频率,例如将8MHz的HSE作为PLL基准输入,最高可以9倍频,产生72MHz的输出频率提供给系统时钟;其余的电路只能进行分频,如TIM、USART等这些外设时钟都是通过系统时钟分频而来,所以它们的最大频率不会超过系统主时钟。
6 P6 R2 V0 H' ]2 {' p* _! h8 h" b  b- `) s1 L4 {) y
三、时钟配置流程2 p+ `# P- {# y
STM32F10x时钟的配置有很多种方式,如果HSE存在,那么可以使用HSE作为PLL输入,也可以不使用,还可以将HSE 128分频作为RTC时钟;当HSE不存在时,可以直接把HSI作为系统主时钟(8MHz),也可以将HSI作为PLL的输入,但此时PLL的最大输出为64MHz。LSE存在时,可以将LSE作为RTC时钟,也可以将LSI作为RTC时钟,看门狗的时钟只能是LSI(40KHz左右)。
8 w! u& [, j& T0 H; _1 k下面是STM32F10x系统主时钟及总线时钟配置流程:. k% Q- d* Y. q$ c4 S) r+ x
+ }) v3 H- D3 x& e/ `+ b' V" Q
TKY9]30$(OE40S(7([JIRBE.png

8 k; n% Y3 S& o$ e7 k5 a- s4 D* c; @4 j
1.任意时钟倍频或者分频系数必须在该时钟未使能之前修改,例如PLL倍频系数,当PLL时钟使能后,该倍频系数数被锁定,无法修改,必须先失能PLL,再修改参数,其他时钟亦是如此。4 H, b/ K9 d% s% m: B; J
  Y/ v6 d1 ]$ t: @: e  T
2.PLL时钟、RTC时钟、系统时钟源切换时,只有当目标时钟就绪时才会切换,否则无法切换。一旦某个时钟源被确定,除非复位,该时钟源不会被停止
! J1 C. e$ p2 ?/ m) P+ G9 k$ R/ g# V, J
现根据上述流程,一步一步的进行时钟配置:* X; Z% l2 p, ^/ c) [/ |
尽管时钟树如此复杂,但实际上也就需要配置以下两个寄存器即可!
1 k1 W1 _/ n2 S
% y) i3 w8 _! M
9QOT@@1GNOR)TQDH9DSC{_3.png

, [/ G0 R3 U. b
6 o& i: }6 k3 {3 `5 S  c. l8 [& H0 A
)F$VH~58H8C{`NFQB_N_E`S.png
, \- m& P) ^4 {8 e

1 M3 a' {5 E3 @6 dHSE配置(如HSE不存在则时钟错误); n2 U/ j/ h4 O
  1. RCC->CR |= (1<<16);//使能HSE
    3 B/ n, D9 @/ g. ~3 G
  2. while((RCC->CR & (1 << 17))==0);//等待HSE就绪' ^$ G: Z, J7 J
  3. RCC->CR |= (1<<19);//如果外部 8-24MHz振荡器就绪,时钟监测器开启。
    6 Z9 q5 ]+ J; O
  4. , R: Y& k. z! G, I; d3 f8 p8 e
  5. //下面是HSI配置 若有需要可以加上2 G/ L5 H9 e# v. _0 Y
  6. RCC->CR |= (0x01);//使能HSI
    # ?& o4 a1 i* h$ p; A
  7. while((RCC->CR & 0x02)==0);//等待HSI就绪
复制代码
  v" l7 H. |) x* Q$ T* a
FLASH访问配置
& G# ]5 _( `+ c* u$ u" w$ D# P2 V5 c
  1. FLASH->ACR | = 0x10;//FLASH启用预取缓冲区
    ' ~8 V, |: t7 a5 g
  2. FLASH->ACR & = 0x03;//清0低2位
    . s, M/ {. d% |3 x* _/ }
  3. FLASH->ACR |=0x02;//等待2个周期
复制代码

! G( I7 W1 U2 B9 C# K0 XAHB、APB时钟分频系数配置
- V: m9 w9 ~! |9 b& x1 x
  1. RCC->CFGR = ((0 & 0xf) << 4)|(RCC->CFGR & ~(0xf << 4));//AHB不分频 72M
    ( H" ^2 }+ A$ R0 }! x& |6 d
  2. RCC->CFGR = ((4 & 0x7) << 8)|(RCC->CFGR & ~(0x7 << 8));//APB1 二分频 36M
    9 q5 }3 K: b* O
  3. RCC->CFGR = ((0 & 0x7) << 11)|(RCC->CFGR & ~(0x7 << 11));//APB2 不分频  72M
复制代码

/ d6 p* }1 u9 q7 T: M& @$ UPLL配置$ |8 M9 X% o% u. _
  1. RCC->CFGR = ((7 & 0xf) << 18)|(RCC->CFGR & ~(0xf << 18));//PLL输出9倍频  8M*9=72M
    / X0 k1 Q0 q6 G5 e* u* a/ u* h
  2. RCC->CFGR = ((1 & 0x01) << 16)|(RCC->CFGR & ~(0x01 << 16));//PLL时钟源选择HSE
    8 z9 {" A. x2 F8 I1 R
  3. RCC->CFGR = ((0 & 0x01) << 17)|(RCC->CFGR & ~(0x01 << 17));//HSE不分频接入PLL
    6 j" S* V# c. s& \4 p+ ]
  4. RCC->CR |= (1<<24);//使能PLL
    & g% U! ?/ |1 j' z# C; P
  5. while((RCC->CR & (1 << 25))==0);//等待PLL就绪
复制代码
5 q! N  N" S3 g5 l. @
系统时钟配置5 G- G6 T7 R; ]$ m) R' ^
  1. RCC->CFGR = (0x02 & 0x03)|(RCC->CFGR & ~(0x03));//系统时钟源选择PLL0 i0 r6 ~9 y: C
  2. while((RCC->CFGR & 0x0c)!=0x08);//等待PLL作为系统时钟源就绪
复制代码

" {5 a+ p/ E% }) |* p这样系统时钟就配置完成了,如果HSE接的是8MHz晶振,那么SYSCLK=AHB=APB2=72MHz,APB1=36MHz 。这里并没有开启RTC、USB等时钟,大家可以根据需要自行开启。4 l1 \8 x$ f8 Q! h8 w/ _
对系统时钟的初始化,在STM32F10x的库函数system_stm32f10x.c文件中:SystemInit函数也有类似的实现方法,大家也可以参考下。
. E# a, T* d9 b8 ]9 _5 {  ?3 [1 |( j: S$ O4 q$ W3 F
四、备注
' F0 y/ h/ `/ T系统复位后,HSI 振荡器被选为系统时钟。
) j9 o) k' R+ M$ I' z4 H8 \
) o0 x1 P# {4 l  W! s时钟安全系统可以通过软件被激活。一旦其被激活,时钟监测器将在 HSE 振荡器启动延迟后被使能,并在 HSE 时钟关闭后关闭。如果 HSE 时钟发生故障,此振荡器自动地被关闭,时钟失效事件将被送到高级定时器 TIM1 的断路输入端,并产生时钟安全中断 CSSI,允许软件完成营救操作。此 CSSI 中断被连接到 Cortex-M3 NMI 的中断。% j7 N$ `9 t+ e7 [5 b/ t( E

! Q  x  I% {- b- {如果独立看门狗已经由硬件选项或软件启动,LSI 振荡器将被强制在打开状态,并且不能被关闭。在 LSI 振荡器稳定后,时钟供应给 IWDG。
8 _/ B: C& ?) C0 U' I/ b. K9 T4 P- w' H# \$ [
FLASH预取缓冲器:* n1 |: f7 [) ^5 ]* O  ]: s) v
$ j/ X9 U0 f  ^- J" |7 F
复位后预取缓冲器处于开启状态
. k" E, V6 y8 J# g5 X! J+ }* ~! S/ v5 X% N* g6 Z
只有当SYSCLK低于24MHz时才能转换预取缓冲器的开启/关闭状态。通常在系统的初始化程序中开启或关闭预取缓冲器,此时微控制器运行于内部的8MHz阻容振荡器(HSI)。
* {0 e8 u" }& K( ~. i4 _  p( v& D% _4 v& t9 g5 s
注意:当 AHB 时钟的预分频系数不为 ’1’ 时,必须打开预取缓冲器 (FLASH_ACR[4]=1) 。如果在系统中没有高频率的时钟,即HCLK频率较低时,闪存的访问只需半个HCLK周期(半周期的闪存访问只能在时钟频率低于8MHz时进行,使用HSI或HSE并且关闭PLL时可得到这样的频率);在闪存访问控制寄存器中有一个控制位(FLASH_ACR[3])可以选择这种工作方式。
. e! W6 Y& ]. F
, X" v" w6 c/ ^5 Q0 k3 h3 Q' j6 i注意:当使用了预取缓冲器和 AHB 时钟的预分频系数不为 ’1’ 时,不能使用半周期访问方式。
; W6 v" \0 q& C$ [
& g. ?" m. N: N0 @" d5 ~0 t
' F/ e: ?0 _3 ?5 ~# y7 e; w; h2 V+ ?7 M3 e% ^" G3 C' X
_T]8Z)V%2VIEX0BYS2831MD.png
PIAPW74SGTJHC43G4%2L$VY.png
收藏 评论0 发布时间:2021-11-30 22:16

举报

0个回答

所属标签

相似分享

官网相关资源

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