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

STM32学习笔记02—时钟树架构

[复制链接]
STMCU-管管 发布时间:2020-10-27 13:51
STM32学习笔记02—时钟树架构

, N* ]! C: x$ E. g: _. i2.1 时钟树结构图6 W) B7 m! C8 @
       STM32属于Cortex-M3内核的单片机,时钟结构比之前的51单片机较复杂的多,根据数据手册,STM32F103的时钟结构如下图所示。' Z3 F2 Z# m) R
1.png
    根据上图可以看到,STM32F103系列单片机具有4个时钟源,内部的8MHz时钟发生器,外部的晶体振荡器接口,最高支持16MHz,外部的32.768kHz晶体振荡器接口和内部的40kHz时钟发生器,其中32.768kHz和40kHz主要用于内部RTC时钟脉冲,8MHz的晶振通过PLL时钟倍乘器,将系统总线时钟提高为72MHz。! T5 N$ j/ _$ a7 Z: j- R
4 {1 k/ h' i* X; u. D1 S
$ E5 }# a3 R4 A0 ?% @
       STM32F103系列内部具有2条外设时钟总线,APB1和APB2,其中APB2的时钟最高可达72MHz,APB1的时钟最高可达36MHz,通过配置对应的寄存器,就可以将CPU内核时钟提高到最大速度。7 _+ S' [$ f; c* ?
  y7 O2 a* M1 z6 F  e# U2 R

7 I5 M  K, R- `: q/ H       通过最小系统可以看到,我们使用外部高速晶体振荡器接口,外接8MHz晶振,RTC则是使用32.768kHz晶振,现在我们来通过数据手册来配置对应的寄存器位来配置APB2时钟达到72MHz,APB1时钟达到36MHz。
0 ~1 W' M; w+ D6 E( c1 X2 J; c$ f; A) a* P6 b
6 f7 Z! C' p" L& _2 H4 f  K4 a
2.2 时钟配置- u; @6 W4 ~7 F, Q
2.png
       上图是ST公司推出的一款软件,这款软件可以自动生成寄存器代码,但是我们在这里只用到其中提供的时钟配置功能,通过上面的时钟结构,我们可以得到配置时钟的大概流程。
' A& F6 D: Q) ]; i" H7 @  ^5 ~! v. L) G" ^8 X

' ?% f$ m  P' q5 u+ k- p  A2.2.1 时钟配置流程% g7 B  T7 q. D8 G1 t
(1)开启HSE时钟接口,这个接口用于使能晶体振荡器输入端;
, J& u; _+ c$ c7 u2 Z" v# i8 u& T' G2 q" W& A

1 o% i; x2 g# L; x(2)设置PLL倍频系数为9,因为外接8MHz时钟,所以设置系数为9就可以轻松达到8×9=72MHz的时钟频率;7 ?5 N& t( W5 o9 f; y

; O3 V3 C1 ?$ k5 B' b( |6 L
0 W5 m( F, m# T, M2 y
(3)设置时钟源为PLLCLK,因为HSE使用的时候可以发现最终的输出就是PLL时钟脉冲;
1 n' A) w1 {/ E; k. K* l# ~4 F: z! O' Y( X  Y( v( F
! h  }* @( a/ c) m/ A
(4)设置APB1时钟总线的分频系数为2,因为APB1时钟总线最高频率只有36MHz;
' [) a6 _- }& V9 d+ S$ Y
* Z' E0 ~  d1 r1 x" y, o

' C2 M8 g% m7 x, U& d$ o( S(5)设置APB2时钟总线的分频系数为1。
7 T% E4 z5 t- i# v3 x: @5 }8 e; W1 C& H& g

! ^* L  `; n. {* n& w- l- N8 I9 ^: T2.2.2 相关寄存器0 Q3 I/ |0 M- o8 m5 A5 B3 p9 R
(1)时钟控制寄存器:RCC_CR
- L( a/ M" h4 Y0 \9 h! y  h
3.png
Bit 25:PLL准备状态) A  g2 f4 m5 r, u7 s4 ]# L
4 w6 f  n) I; N' L) A

" L0 k) f3 A: G& B6 `/ G              0:PLL解锁
+ g! a( v9 I6 l! |% ]5 P/ S: X1 T. P4 |9 D- i6 ?' a! {
- \9 P! r/ v) s4 S7 S
              1:PLL锁定/ Z* r% L5 j. N; M5 c( T
9 C: v6 i' W, c; N) M

. W- x7 X  P* A$ l) rBit 24:PLL使能
( R5 J* x0 _; |+ n/ w$ p2 ~5 J6 K  p8 ^/ H( P! Z" Y, n

9 l  V2 a5 S0 i              0:PLL关闭# K8 ?3 K* w. Y" Y$ K8 ~0 g
              1:PLL打开( i0 K$ d* H# d

: ]- [5 o. \8 S1 l: }

4 ?( g2 m3 R; A# `; GBit 19:时钟安全系统开关/ N- @% L+ b* ]9 J+ N0 Q5 ]6 C

& B  s+ V$ h7 j$ A6 x
+ o7 ]% D  \/ y: z1 W  ]6 q# H
              0:时钟保护关闭
# r" y6 q0 S) a3 u  i7 C  ^8 b* Z& I              1:时钟保护打开$ a4 z. K% L% L, s$ `

( s+ T" @5 q8 ^, i  R+ N$ ^9 @

  x: h3 z/ y7 w- X) aBit 18:HSE旁路(禁用HSE振荡器时才能写入)
/ Y7 h$ d- ?0 T1 L: {  p$ l9 J* Q8 D7 Q" A

& Y' k9 q1 u0 u- R& G% b' m              0:HSE禁止旁路& S) E' [6 c& H# ~4 s
              1:HSE打开旁路
7 d0 m! B2 ~5 j4 A+ |% L" w# e* N
9 v8 D: Q; }9 g

9 a. U* A! X& R6 {Bit 17:HSE准备状态
2 }( z/ S4 y% d' t5 a0 R( C- h& N/ Y2 Y/ k6 h) c

) `0 i8 y9 z0 O              0:HSE未准备好4 o( }# n3 S6 O  Y1 [5 Q6 }$ h
              1:HSE准备完毕! }' S  B. ?' n6 v& X& L# }
" X0 [/ {3 o# {- h! L% {) d2 o
2 C2 p! W6 [% F% z) F% z, f0 S
Bit 16:HSE时钟使能3 E$ ], B9 m4 ^  M8 ~- G+ a4 I

! O; _& ~; A2 I/ S
4 o5 m9 p* B8 V/ l1 N! H
              0:HSE时钟关闭! {, _* b6 m" i
              1:HSE时钟打开7 ]- }* O& {5 n3 Q; I: x

, Z. O. `" Y7 s) q$ u  `) X2 s
' O4 g# N. e1 }" B9 O8 p4 h* {
Bit 15~ Bit 8:HSI校准值(这个值在启动的时候自动初始化)+ k' [2 N2 e3 X2 |
, ~; u5 ~  k1 z" s! e& l) ~9 b
0 J* ^' v) m: C/ n. E3 Q% Q
Bit 7~ Bit 3:HSI微调(对其进行编程以适应电压和温度的变化影响内部HSI的频率。初始值16,步长约为40kHz)6 x- `6 ]6 r) f3 W3 E1 R
( h0 ]5 c% z. H/ U, [& M3 h' E
( o. Q( r' o  \' k7 S  ^
Bit 1:HSI准备状态) @3 ~# \- }9 b  H/ q* s0 F! ?
' M9 U5 X" Y, n) @1 T- y
/ q  `. F4 _7 K; {4 V' C
              0:HIS未准备好4 k# Q; }4 h3 u- r9 X/ [* \
              1:HSI准备完毕
$ Z$ E* q% A8 w/ L/ K1 |, i7 N$ c# K/ ~$ m
( f8 ~5 }( |% A+ h7 A! {- q
Bit 0:HSI时钟使能/ z4 c3 M2 M# {9 G  f% Z$ e4 K

. N( [5 w. p4 S* G

, s. P- b; r2 F! ^5 Q- p% x$ T1 H              0:HIS时钟关闭- a. K$ ^3 U$ ]4 x
              1:HSI时钟开启8 R) b" \3 A' t. i
, a9 F" e0 |! _$ a$ n$ t

" b7 P: f  u' q% j2 i" [  x
( c9 p- m; B' R# y- t(2)时钟配置寄存器:RCC_CFGR: g( ?" H( o& D/ F$ i4 \, V
4.png
Bit 26~Bit 24:芯片时钟输出) m( c, M. ]# q+ S
! C' C+ B5 c' Y& Z" {

' B2 R. ^- V8 v; H; M; F              0xx:禁止输出
: b1 S7 J6 a; G  E5 V              100:选择系统时钟SYSCLK
/ u7 Z' x3 E: \$ w- w6 x              101:选择HSI时钟, D2 m% r/ g+ F4 M- {
              110:选择HSE时钟) C( n7 l+ o8 G- V. `( X/ L
              111:选择PLL分频输出(2分频)
1 l5 _- [$ X3 x: t- ]6 A$ o+ t6 k. H$ @4 s6 n7 P1 V" ?2 I

# k- H0 A( p1 }& j2 z9 E; CBit 22:USB时钟分频系数3 A/ V1 J& u& I& z0 l

; W, z) M1 r$ D8 r8 M) i, {
+ v7 ]( J3 M+ k) m' p) d) z
              0:PLL时钟1.5分频作为USB时钟
9 [- s" T! a6 S6 f  w% v6 x: R, ]              1:PLL时钟不分频作为USB时钟
' h4 {: `  K9 {6 c7 E( @- Z! t+ y8 t/ b) L7 X: ]

# c/ R' y$ M( K# i" ^/ eBit 21~Bit 18:PLL倍频系数
6 m# `3 [+ a* `) X$ y; c9 c/ ^$ i  A7 G: D
8 v; J' \& S3 z5 ]: m
              0000:2倍频5 \4 v# }% e  U; _+ {: D+ O& |
              0001:3倍频
$ p( ?1 P( I+ h" A1 t( a              0010:4倍频7 Y: ~/ E0 Z' ?" {; l
              0011:5倍频
8 B$ l3 k% L0 k4 F% A6 ^              0100:6倍频0 }, u- ?* P  Z3 j5 J
              0101:7倍频3 S6 g, I; f  l1 f. |* r! p# G
              0110:8倍频$ _/ q5 B4 L8 s8 @+ n+ L+ |# k
              0111:9倍频! o( m( l% b) b. N' d/ E+ D* l
              1000:10倍频
0 B! \" v( l% w% |( d              1001:11倍频; W( {; R0 M1 E6 Z
              1010:12倍频
) q" e1 d# \" U0 L: S$ V) d/ k# c              1011:13倍频
+ m2 g2 a$ D7 h( l' `# C              1100:14倍频# K; w: o1 {% o4 `
              1101:15倍频4 P  Y- t+ |7 I5 T: A. U! T
              1110:16倍频+ k( p2 Q& T2 O7 T$ T: m3 }
              1111:16倍频
, d# p6 v/ O9 ?+ a% x! F" `, x
! q( v* O% w" Q% y# C

1 |) E. u! ~& v8 R' m; mBit 17:HSE输入分频器
% j4 \/ g3 p  T7 y0 K4 m+ K4 w
+ T. q' ^$ F) {  N, j
% U+ n0 a$ ~% P9 q
              0:HSE输入不分频
7 T3 N: j# M6 E9 u/ S) ]              1:HSE输入2分频* ?; Q6 y/ C  k+ u7 ^; y$ t

7 {2 A! h- S$ T& y7 U0 Y
" B5 w% L) M1 l6 Q$ E# V
Bit 16:PLL时钟选择(PLL处于禁止模式才能写入)
1 l, M6 K* _7 J, J! C7 H
& a# g! [' M) @, h! M

6 x6 B& K2 {* p) r              0:HSI时钟2分频作为PLL时钟输入, X: L2 X. ~. i/ B7 }
              1:HSE作为PLL时钟输入
' m# l% n  P6 i( P# B) i: u8 T) Q# J/ j/ E& |% s: ?( L

6 H9 S" X, o. oBit 15~Bit 14:ADC分频系数# y" x4 H& z/ Y- L$ N

; F, u! t0 P9 C! O/ }' @

& p" `7 L& N9 s5 r# b( v! B% W  v              00:PCLK2分频系数为2
2 O' W3 }$ i, l% z1 d              01:PCLK2分频系数为4
- Y$ N; L. e1 M7 V) Y" O              10:PCLK2分频系数为6# O0 K% ]+ K+ e$ G6 B
              11:PCLK2分频系数为8
+ X, ~$ W+ k( o! u4 E$ M5 R9 Z' \
' Y8 r) c; y- L3 g7 F% L  o
Bit 13~Bit 11:APB2分频系数(最高可达72MHz)
% _( P! }8 L" Y# A1 ]) S) q6 D
3 r- D$ P4 ?  X% g5 [

8 [+ ~: W7 u8 S. n7 `. F) M, v0 T              0xx:HCLK不分频1 k2 ^5 k, ?4 ?
              100:HCLK分频系数为2
( p' a/ H! o4 f, K, u6 b" n& S1 n& Z              101:HCLK分频系数为4
. X! _& D) X/ A3 w( S0 |              110:HCLK分频系数为84 ~  t3 w& _$ ?
              111:HCLK分频系数为16! l% y( X$ x( j1 t" p
2 ]# T1 x  ]. x8 j$ f
2 A) x6 l/ n6 B
Bit 10~Bit 8:APB1分频系数(最高只能达到36MHz)
" \! H) e" j9 U9 G8 k+ J7 E0 M1 R" T
  E- N+ s3 x! H5 C2 b, D% k; r
              0xx:HCLK不分频
- Y! k+ X* \/ K$ U% b              100:HCLK分频系数为2/ t& Q& `3 l1 j! i8 P
              101:HCLK分频系数为4
4 M& v9 L* j. v; I# {5 R# Q; m              110:HCLK分频系数为86 w' H. I& z1 }  R
              111:HCLK分频系数为16
4 G6 M# y4 X+ _! E$ N0 X- B1 E! E2 ?9 d

, B  F0 H. N: m6 ?' HBit 7~Bit 4:AHB总线预分频系数
# s0 b" ]6 L) \. p  D
4 ?- x% a, z6 l+ ~* h1 W2 M6 N4 o2 J

# u2 e& l. f' c: P; W( g  T              0xxx:SYSCLK不分频7 q+ T, i& u; c: f  }9 t; Z
              1000:SYSCLK分频系数为2
; d8 W# p1 H) c! ~$ O) f5 _% y$ E$ ~. V              1001:SYSCLK分频系数为4
1 ~( }& e5 e& ^; ~  s: P, y7 H              1010:SYSCLK分频系数为8
6 f4 N2 S0 Y7 O' y6 t              1011:SYSCLK分频系数为16
; {  \% Y7 k* {- u5 s0 s              1100:SYSCLK分频系数为644 [, b. |" t6 N1 l  A
              1101:SYSCLK分频系数为128. T- P( X8 w( ~
              1110:SYSCLK分频系数为256
* @  ?5 i) D# g              1111:SYSCLK分频系数为512
1 Z6 k3 Q6 A$ F9 E) Q, ~6 S+ o) {' g( e0 f- Z' n8 w8 O) b9 m
5 v: h1 D; Q4 w
Bit 3~Bit 2:系统时钟选择状态
, d/ U# A$ Q( }1 L5 s5 z+ B0 I8 N3 {( z7 H$ E2 ]

* {( L: t# h  s% R" A1 e              00:HSI作为系统时钟: W/ U) }$ d. G, Z7 G1 w
              01:HSE作为系统时钟+ M! ]2 U6 |6 q- n- F
              10:PLL作为系统时钟. k& S: n/ O. Q/ }1 E, O; [
              11:保留$ T1 z9 Z' B0 Z6 [
# R+ N8 N4 ]: v0 F$ s3 E

# l. U6 D( o( V7 m9 t4 @/ lBit 1~Bit 0:系统时钟选择8 y  v% \- \2 e
, g7 k7 S9 e. j: Z( W

& q5 V- i9 z) m" `, p. |4 K              00:选择HSI作为系统时钟4 }5 v1 Y3 e' n! P; L
              01:选择HSE作为系统时钟3 e! n+ F( L+ [% w( A
              10:选择PLL作为系统时钟
9 b6 G% V% z; L6 f2 N              11:保留% j  g5 f$ S( z
  G& [9 W: _' V. N7 F5 h% n! l# j

3 f" q! Q, W  d( ^2.3 设置例程; k5 E/ I: w! C5 V  J# K

7 z2 X7 l! a5 N1 p, |& U配置STM32的时钟需要创建几个文件,这几个文件如下表所示。
7 r9 n" E% p! Y! D, G  F
5.png
(1)创建上述三个文件,其中c文件添加进工程中,h文件包含进程序中,如下图所示。# }8 j! S2 O- B  }- R- s% `) o
6.png
7.png
(2)stm32f103x.h文件输入以下内容:! S. H7 S- L7 q' r3 g
8.png
    这个文件用于定义程序用到的所有寄存器的地址和结构体,是整个STM32程序的最基础的文件。
; P2 Z: Z& c+ l5 w
& |0 W8 g3 t* U; C. W1 i
& T! O5 [- f! N4 m) B$ A
(3)sys.h输入以下内容! V1 Y6 N1 p* D7 N5 Y. P
9.png
    sys.h文件用于定义STM32的时钟配置和中断配置,以及后面的端口位操作模式。
  k3 `8 [' g, E6 r' I$ Q) q) Z$ P" y
$ ~6 E% \6 l$ `% P6 ?& B5 M

$ g4 m1 c- f3 N# i! f4 {5 S) S) p/ H) g
(3)sys.c文件输入以下内容+ L2 \% c- R9 }$ q+ r
  1. void STM32_Clock_Init( u8 PLL )
    & S, }7 C/ F  g$ M/ C1 M* ^+ @4 j) v
  2. {
    % v6 p+ b2 \" `4 G" y- B$ Z
  3.    RCC->CR |= 0x00010000 ;              //外部高速时钟使能HSEON
    : {" N, W6 N8 ^+ z3 K6 x6 n9 v
  4.   while( !( RCC->CR>>17 ) ) ;              //等待外部时钟就绪( D2 j$ g8 {# L1 K: e
  5.   RCC->CFGR = 0x00000400 ;            //APB1=DIV2;APB2=DIV1;AHB=DIV1;
    * [' W$ D5 r6 p* ~6 R% b
  6.   PLL -= 2 ;                    //抵消2个单位(因为是从2开始的,设置0就是2)
    - V, m, c0 c6 d
  7.   RCC->CFGR |= ( u32 )PLL<<18 ;            //设置PLL值 2~16
    2 u6 T$ X% i% @' w
  8.   RCC->CFGR |= 1<<16 ;              //PLLSRC ON
    0 H7 n" I5 Q' ^: \& B. N
  9.   FLASH->ACR |= 0x32 ;                //FLASH 2个延时周期
    9 x/ X. C+ a2 A3 E) ]
  10.   RCC->CR |= 1<<24 ;                //PLLON0 |3 w) {# ?) l/ m
  11.   while( ( RCC->CR&0x02000000 )!=0x02000000 ) ;    //等待PLL锁定
    , @9 N6 m6 j- D/ n* \/ n" X
  12.   RCC->CFGR |= 0x00000002 ;            //PLL作为系统时钟
    & Q1 B  C6 H# Q8 U! Y
  13.   while( ( RCC->CFGR&0x0000000C )!=0x00000008 ) ;  //等待PLL作为系统时钟设置成功
    ) d# d- M5 R0 R4 i- b
  14. }
复制代码
% L8 k) F; Y/ K3 \- B( M8 h& b
   这个文件的函数就是真正配置时钟的过程,可以对照之前描述的配置时钟的过程来看这段代码。* r% x( o  \, {# ?" n
上一篇:1 b) R. ^1 G; M- g
STM32学习笔记01—STM32F103环境搭建>>7 }+ ?9 I: V: g* V3 D6 r& C
5 B2 a  e) P1 b

0 u2 A3 A' T" W  j/ U% v; S1 G/ V6 N) M

8 v- z9 r- H& J3 \
' A1 I, u$ y- D' C/ G! {
赞 收藏 评论1 发布时间:2020-10-27 13:51

举报

1个回答
开发者 回答时间:2020-10-28 16:58:11
2 n. H% g; o) r; Z/ Z, F+ q- }1 V
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版