|
STM32学习笔记3——时钟系统 . i& Q( u7 C: n
时钟系统结构大致如下图:
! y$ D# R& M$ ]; s' G
J6 n& t% Y# j( H }7 K; N/ G. X
1.时钟树详解
B- {' I6 J, H1 E
6 C/ B" O8 |* O# W& e, v" X
' J7 x, L- _, q* y先看上半部分。
* ? i' f, k# e+ w1 `) C3 D从上往下有:
" @; m M" M3 Y& D$ ~" Y1. 独立看门狗时钟由LSI即低速内部时钟(RC时钟)产生,大致为32kHz,由于是RC电路产生,故时钟不稳定 # x7 N! m( O$ ?0 F% j9 d
2. RTC可以选择上面的LSI时钟产生,也可以由低速外部时钟(LSE)产生,大小为32.768khz,具有功耗低,精度高特点 @# G# X y- ^7 g
3. MCO1/2是时钟输出管脚,每个管脚可以输出4种时钟源大小,具体可在图中看出,但最高不能超过100MHZ # {7 M ~: P. \- d6 C
4. 系统时钟有三个来源;高速内部时钟(HSI)大小为16MHZ,高速外部时钟(HSE)通过OSC_OUT/IN接外部时钟或晶振,以及锁相(PLL)输出时钟,一般采用锁相环可以达到最大值168MHZ $ ~& J4 w3 Z, \4 t# m- j7 v1 g# ]
5. 主锁相环主要通过HSE(常用)或者HSI作为输入,然后*N/(M*P) 作为系统时钟的输入源之一,走/Q则供给USB,随机数发送器及SDIO时钟。
8 E% v% \, z, m副锁相环则是专用供给I2S(音频总线)时钟,可以来源外部时钟输入,HSE或者HSI
5 {% v- w1 ?' s8 ^4 |0 @- b& D* C. p6. 以太网和USB时钟, t4 d, a9 ^% `
/ Y! x# g. B( Z; Y" k4 p( C
相关寄存器
# m) O6 J7 ?* |7 Z8 L4 {4 x1 }- }
2 u% W2 t: Q; E一般来说,我们希望HCLK能达到最大速度即168MHZ,故我们常常采用锁相环输出。首先看CFGR寄存器:
0 C0 U* L( l# K- b* z8 T
N @ | e) \HPRE是HCLK时钟分频,一般我们在此直接设为0000
" ]8 p+ D! p/ g' U/ hPPRE1/2为APB1/2时钟分频,其大小如下图: 7 V/ C" ?' R& ^$ G, C; w5 u- A
) l @: Q; z2 m1 d
) D! k) d7 H. N( C: q# [
按需要设置即可
$ T5 E, R" l$ R3 a! rPLL_CFGR寄存器:+ X7 z8 M8 g5 ] h! d' }* u
1 n- u2 f8 R0 }1 C+ Q; `主要设置主/副PLL中 PQR分频系数的值和选择HSE/HSI作为时钟输入2 z& @ N/ h" x
4 M" A) t4 ?, k
RCC时钟控制寄存器,主要控制PLL和HSI,HSE时钟的使能和开关 ' T. r/ Q7 F; l6 n/ o
! ~$ x8 [7 }" b
0 H- f; H; {" h2 g* }# M时钟使能寄存器:任何外设开始时候都必须使能时钟。操作非常简单,寄存器置1即使能。7 h' ]/ Y9 R; d) ~9 J+ {
4 D+ j: s& c& X7 D) @" r实例:! T& Z( h. M* y( _9 s c E2 h6 _
- <font size="2">//返回值:0,成功;1,失败。+ S) c: D$ ?, q- ]# ^/ ^2 g
- u8 Sys_Clock_Set(u32 plln,u32 pllm,u32 pllp,u32 pllq)) S$ @- `; S( k6 M9 m& N) O g
- {
6 B3 J9 n% G: e - u16 retry=0;
* K% N/ h$ @3 }$ s, R - u8 status=0;. q' l$ G2 m7 ]- |+ [/ K
- RCC->CR|=1<<16; //HSE 开启
$ h$ T, j# `( @2 ?& z - while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待HSE RDY; U4 o" F; S b& I8 X, b3 `4 \+ L
- if(retry==0X1FFF)status=1; //HSE无法就绪
5 _. x" |! C! S: O% w& H5 M8 { - else
& d8 O; ^; ~0 J# Q! P: t b - {
" U9 ]& Z* e* S4 R P" s) p- w - RCC->APB1ENR|=1<<28; //电源接口时钟使能1 T& x* j' D1 c: E5 j
- PWR->CR|=3<<14; //高性能模式,时钟可到168Mhz0 m1 G: M) e) g! w
- RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频.
3 d* ?$ J8 z4 y1 M! C6 a - RCC->CR&=~(1<<24); //关闭主PLL
% Y6 ?, j" c/ ?. v$ d - RCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置主PLL,PLL时钟源来自HSE
; ]0 S) ]0 n9 j8 i! N - RCC->CR|=1<<24; //打开主PLL4 x/ H+ X$ A0 ~8 s, j/ g
- while((RCC->CR&(1<<25))==0);//等待PLL准备好 4 @* z% B, K8 ]+ q7 h! g4 d
- FLASH->ACR|=1<<8; //指令预取使能.
+ N" b" t8 z7 k1 e; X' W0 I - FLASH->ACR|=1<<9; //指令cache使能. g8 j5 ?% p: |+ Q! z5 P m) x
- FLASH->ACR|=1<<10; //数据cache使能.
" E& Q# W# @. R8 D - FLASH->ACR|=5<<0; //5个CPU等待周期. 8 [3 Z& w T M. w3 Q% e/ B
- RCC->CFGR&=~(3<<0); //清零
' l* ?/ w3 j: K5 e7 { - RCC->CFGR|=2<<0; //选择主PLL作为系统时钟
8 X3 o+ S# [! f) n - while((RCC->CFGR&(3<<2))!=(2<<2));//等待主PLL作为系统时钟成功.
% O) D0 F* {" ?8 W x$ z2 s - }
/ U5 Y: E% a* G& W( w - return status;
. g r' y2 v8 g) `3 ~ - }</font>
复制代码 7 K: o& w* g) ~& |8 Y
|