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

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

[复制链接]
STMCU小助手 发布时间:2021-11-30 22:16
实际上,对于STM32F10x系列的芯片,如果使用库函数方式开发,芯片的时钟初始化函数已经写好,并且在启动文件(例如startup_stm32f10x_hd.s)中被自动调用,在进入main函数之前,系统以及外设时钟均配置完成,main程序中不需要对时钟再进行任何配置,直接编写应用程序即可。但是作为一个底层驱动玩家必须要打破砂锅问到底,看看STM32F10x系列芯片的时钟系统到底是怎么样的以及如何配置时钟,下文将着重分析STM32F10x的时钟系统以及用寄存器方式从零开始一步一步配置时钟。
7 j0 S/ _4 L* R& P6 V3 j- k! w# G7 X+ J0 G8 r0 w- w+ w
一、开发环境; E9 {# O2 j. g2 m
MDK版本:V5.28
9 L9 R6 e: t0 E+ b2 I单片机:STM32F103RCT6
+ _, W+ v& b; v( _6 @, s1 h二、时钟树剖析
; n5 C# l% H! e- ]: R5 c1 F% g7 m0 ^/ k
5}7)N_$J[]~[E6]{CR@H)[Q.png
! S$ L  \' c! }6 ~

2 V4 l) f6 F. k3 W上图就是STM32F10x的时钟树,看着十分复杂,或许有人会问,为什么STM32要把时钟设计的这么复杂?这是因为STM32的外设很多,而且不同的外设需要的时钟是不一样的,例如USB时钟一般需要48MHz,RTC时钟一般是32.768K,APB2总线上的外设最大不超过72MHz,APB1总线外设最大不超过36MHz,如何同时满足这些时钟要求呢?显然如果只设计一种时钟是不可以的,于是就有了上图中复杂的时钟系统。下面我们就来分析下上图的时钟系统。
; y% S0 D8 D2 t+ o
1 E- n6 m4 v$ F8 a首先可以把上图的时钟树划分为以下几个部分:
: l1 z4 K; o8 u9 c' [- x! |: N7 i: I( c( J: @: y& n  `3 j& R
6KXC8$)[K}1`$~AGTTMA(G9.png

2 m! Q3 ]7 ^3 w8 ^/ R4 u! K  m
_T]8Z)V%2VIEX0BYS2831MD.png
4 S3 v8 @# _) R7 {& L+ p

1 W* {: G3 `, [+ s3 |$ p基础时钟介绍:
4 y% p! k, k1 J) l! [  ?# R( u- c" R6 O8 G& w' o  e
$SEZ~2)7W9YS)29YIGNQ`AE.png
# G2 K7 T" l4 R% [/ V8 f0 o* e

6 V( F2 C8 g* D- U基础时钟并不是官方提出的概念,是我个人的习惯叫法,它主要指的是HSE、LSE、HSI、LSI这四种时钟源,其主要作用如上图所示。0 n1 e/ b! n* Z' D: |/ V) D3 B5 \) x
$ l1 D% E( c* @. M- u4 {  Y* y4 i
系统时钟的产生:
& c+ i: I7 y) p0 O4 y9 h0 u
) f/ d$ F2 f8 [4 ]
ZXIP7BFKM02TZ%`[2YG_XQN.png
2 i2 _, v7 h3 K6 F: B
; `1 a( s, B& i7 g  G; R
系统时钟的产生有三种方式:1>HSI内部高速时钟,一般为8MHz。 2>HSE外部高速时钟,一般为8MHz晶振。 3>PLL电路,输出频率可任意配置。其中HSI和HSE都属于基础时钟,如果使用PLL时钟作为系统时钟,PLL电路的基准输入必须是HSE或者HSI。
1 D% a. `8 S8 f. A  T如果直接使用基础时钟作为系统时钟,那么系统时钟最大频率≤HSE/HSI 如果使用PLL输出时钟作为系统时钟,那么系统时钟最大频率≤72MHz. l2 F. Y6 K. S; @" P

8 D& b1 q1 c+ P8 g3 N- k# n% b下面就以定时器为例说明上述各个时钟之间的供需关系:7 `  k3 c" f5 `$ D, p4 t
0 ]( M' _) @4 p% u; S4 j% t
如果需要使用定时器,那么首先需要开启定时器的时钟,而定时器属于外设,因此需要系统时钟提供时钟给这个外设,对于系统时钟,有两种方式提供,一种是由基础时钟(内部或外部基础时钟源)直接提供,缺点是无法产生更高的频率,时钟源是多高的频率,系统时钟最大不会超过这个频率;第二种是由PLL电路提供,优点是能够产生各种高频稳定的时钟频率,但是也需要基础时钟提供基准信号,且一般情况下STM32F10x系列PLL输出最大不超过72MHz。
$ ^  [" r3 i/ F, D$ n- ~6 U一般来说除RTC外所有的外设时钟(TIM、GPIO、DMA、USART、USB等等)必须由系统时钟提供,但某些特殊外设需要另当别论(以太网、I2S设备等)
% u0 g3 ^! n( l$ h3 L  Y3 O
0 Z( a, @* s5 d) W1 O7 }: M在STM32时钟树中,还有很多的分频器和倍频器,通过这些分频和倍频器就能产生各种需要的频率,但是只有PLL电路才可以倍频,即产生高于输入频率的频率,例如将8MHz的HSE作为PLL基准输入,最高可以9倍频,产生72MHz的输出频率提供给系统时钟;其余的电路只能进行分频,如TIM、USART等这些外设时钟都是通过系统时钟分频而来,所以它们的最大频率不会超过系统主时钟。
" Z; s- s& z; N. _2 c! I6 A4 M: b
三、时钟配置流程
* }- i5 c% ?  z" G0 @  s- |STM32F10x时钟的配置有很多种方式,如果HSE存在,那么可以使用HSE作为PLL输入,也可以不使用,还可以将HSE 128分频作为RTC时钟;当HSE不存在时,可以直接把HSI作为系统主时钟(8MHz),也可以将HSI作为PLL的输入,但此时PLL的最大输出为64MHz。LSE存在时,可以将LSE作为RTC时钟,也可以将LSI作为RTC时钟,看门狗的时钟只能是LSI(40KHz左右)。3 w$ w( |* b/ ]! q
下面是STM32F10x系统主时钟及总线时钟配置流程:
# j; Z- G9 L* S9 `' [
5 j# C! K4 a- k" S
TKY9]30$(OE40S(7([JIRBE.png

$ i7 @: n+ H+ g% w
# v7 N/ W2 y% ?1.任意时钟倍频或者分频系数必须在该时钟未使能之前修改,例如PLL倍频系数,当PLL时钟使能后,该倍频系数数被锁定,无法修改,必须先失能PLL,再修改参数,其他时钟亦是如此。* I. c. r" @5 w3 u! a& I

: ]9 U- J0 y$ m- V2 M7 g2.PLL时钟、RTC时钟、系统时钟源切换时,只有当目标时钟就绪时才会切换,否则无法切换。一旦某个时钟源被确定,除非复位,该时钟源不会被停止
3 q1 A' a8 K( _! E+ O8 ~5 E
* j4 H1 J  e8 Z+ h现根据上述流程,一步一步的进行时钟配置:
2 i( H# F/ ]# _! `+ n# K尽管时钟树如此复杂,但实际上也就需要配置以下两个寄存器即可!
5 x4 E! g+ a  \& K3 j5 b; Q* A, J3 e* J
9QOT@@1GNOR)TQDH9DSC{_3.png

% u# x+ ~7 f# L
& L8 T! P1 ^( `) ?1 z2 T: g
( T8 O' n" M! u
)F$VH~58H8C{`NFQB_N_E`S.png

5 h" l4 f, m: f/ b; u2 s
* F# E) `7 v, iHSE配置(如HSE不存在则时钟错误)
  D% ]& j/ ~5 w5 Q8 J
  1. RCC->CR |= (1<<16);//使能HSE
    ; m1 K( ?3 u# y2 y! X; k7 N! i
  2. while((RCC->CR & (1 << 17))==0);//等待HSE就绪
    ; F* e% C5 H( w% w9 G, T
  3. RCC->CR |= (1<<19);//如果外部 8-24MHz振荡器就绪,时钟监测器开启。
    . y( \7 m* k% ~' |

  4. * [7 l) h# r9 a$ G, f
  5. //下面是HSI配置 若有需要可以加上& x* E3 r9 M  P2 e  H  i  z) @
  6. RCC->CR |= (0x01);//使能HSI
    & W/ X% M; }9 c1 E& Y% A7 w- Y
  7. while((RCC->CR & 0x02)==0);//等待HSI就绪
复制代码
/ `, c" N0 k; v  g8 S3 f7 F
FLASH访问配置5 n) T) R, Z+ u) F* b" c% N
  1. FLASH->ACR | = 0x10;//FLASH启用预取缓冲区
    % V( V9 q! K4 e7 H; M/ q, y
  2. FLASH->ACR & = 0x03;//清0低2位8 z# P9 e+ Y- t9 q
  3. FLASH->ACR |=0x02;//等待2个周期
复制代码

/ f2 R# `4 b+ v- g# c- W4 QAHB、APB时钟分频系数配置
* O# a7 r. [3 f7 s; `
  1. RCC->CFGR = ((0 & 0xf) << 4)|(RCC->CFGR & ~(0xf << 4));//AHB不分频 72M 5 h4 j. Y2 F8 q: {6 S
  2. RCC->CFGR = ((4 & 0x7) << 8)|(RCC->CFGR & ~(0x7 << 8));//APB1 二分频 36M
      c! H7 [4 t) w, E& {8 m
  3. RCC->CFGR = ((0 & 0x7) << 11)|(RCC->CFGR & ~(0x7 << 11));//APB2 不分频  72M
复制代码

7 d/ `6 ]+ M3 G1 D1 VPLL配置4 t. C; q& |5 N5 G
  1. RCC->CFGR = ((7 & 0xf) << 18)|(RCC->CFGR & ~(0xf << 18));//PLL输出9倍频  8M*9=72M
    ' z. v! q: Z4 R
  2. RCC->CFGR = ((1 & 0x01) << 16)|(RCC->CFGR & ~(0x01 << 16));//PLL时钟源选择HSE
    : S2 p  [7 ^  Y- b( F* B3 t
  3. RCC->CFGR = ((0 & 0x01) << 17)|(RCC->CFGR & ~(0x01 << 17));//HSE不分频接入PLL
    0 ]" M* ^3 `! G3 p# w9 b' o
  4. RCC->CR |= (1<<24);//使能PLL/ p) w) o! S5 X. J
  5. while((RCC->CR & (1 << 25))==0);//等待PLL就绪
复制代码
# i1 V9 A# `( q$ E+ ^
系统时钟配置" A$ l! W- t/ @
  1. RCC->CFGR = (0x02 & 0x03)|(RCC->CFGR & ~(0x03));//系统时钟源选择PLL
    . s- d: q$ b5 F6 a0 _* h- p" e1 Y) a
  2. while((RCC->CFGR & 0x0c)!=0x08);//等待PLL作为系统时钟源就绪
复制代码
8 B7 s& I% [' ~0 v- P: T$ l
这样系统时钟就配置完成了,如果HSE接的是8MHz晶振,那么SYSCLK=AHB=APB2=72MHz,APB1=36MHz 。这里并没有开启RTC、USB等时钟,大家可以根据需要自行开启。
; S& U: c$ ?. \5 B1 m对系统时钟的初始化,在STM32F10x的库函数system_stm32f10x.c文件中:SystemInit函数也有类似的实现方法,大家也可以参考下。1 ^( O+ I+ u  \* F8 q

! J' v) T' t) |, z& g( s6 F2 {四、备注* b( z. v8 X% v6 D, G
系统复位后,HSI 振荡器被选为系统时钟。
* @' u. \+ Y/ Y( y/ `5 C3 J* Y" w0 `
时钟安全系统可以通过软件被激活。一旦其被激活,时钟监测器将在 HSE 振荡器启动延迟后被使能,并在 HSE 时钟关闭后关闭。如果 HSE 时钟发生故障,此振荡器自动地被关闭,时钟失效事件将被送到高级定时器 TIM1 的断路输入端,并产生时钟安全中断 CSSI,允许软件完成营救操作。此 CSSI 中断被连接到 Cortex-M3 NMI 的中断。
2 k6 e& w+ X( K! j* C( ?; k1 f3 b0 I
& X% u6 |. ]9 P9 |如果独立看门狗已经由硬件选项或软件启动,LSI 振荡器将被强制在打开状态,并且不能被关闭。在 LSI 振荡器稳定后,时钟供应给 IWDG。
* |$ Y, [- Y* Y7 [4 ~3 x% F1 W8 G
* U2 y2 C8 Z2 g, CFLASH预取缓冲器:+ X: ?6 r; G0 u. S, l
& c) K0 G# r9 ]# m0 Y, d
复位后预取缓冲器处于开启状态( q- S; v6 ?( ?
# q. e( q9 ]" D; F
只有当SYSCLK低于24MHz时才能转换预取缓冲器的开启/关闭状态。通常在系统的初始化程序中开启或关闭预取缓冲器,此时微控制器运行于内部的8MHz阻容振荡器(HSI)。8 i4 ~1 U! \) `, s
! p% |% |7 H2 c6 P3 @
注意:当 AHB 时钟的预分频系数不为 ’1’ 时,必须打开预取缓冲器 (FLASH_ACR[4]=1) 。如果在系统中没有高频率的时钟,即HCLK频率较低时,闪存的访问只需半个HCLK周期(半周期的闪存访问只能在时钟频率低于8MHz时进行,使用HSI或HSE并且关闭PLL时可得到这样的频率);在闪存访问控制寄存器中有一个控制位(FLASH_ACR[3])可以选择这种工作方式。
8 E9 \* f1 }4 ~+ c
/ \! z* C  n" x+ A  }注意:当使用了预取缓冲器和 AHB 时钟的预分频系数不为 ’1’ 时,不能使用半周期访问方式。
$ t9 x" m' j& s3 q
. E& m6 U9 k( Z1 z% U% f9 q: K; j, W% t
; o1 |" [; G& e% Y' b9 j5 P- ~
_T]8Z)V%2VIEX0BYS2831MD.png
PIAPW74SGTJHC43G4%2L$VY.png
收藏 评论0 发布时间:2021-11-30 22:16

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版