|
【STM32】系统时钟RCC详解(超详细,超全面) 1什么是时钟2 F' _* f$ p- v时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。 * k2 i' R- \; |+ j: e 为什么 STM32 要有多个时钟源呢?! w& L3 h! t \; X7 X 0 Y4 D* j7 S; i; k" B% V* ~' h STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费 并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。所以便有了STM32的时钟系统和时钟树, ~. R ^6 i9 c7 [ @3 g1 K ( m' m% J; i N" j. K 总括:2 q- r' ~' V4 A5 d$ L STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,也是为了降低整个芯片的耗能。 系统时钟,是处理器运行时间基准(每一条机器指令一个时钟周期) 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。 一个单片机内提供多个不同的系统时钟,可以适应更多的应用场合。 不同的功能模块会有不同的时钟上限,因此提供不同的时钟,也能在一个单片机内放置更多的功能模块。" f. g6 [: {0 Q3 s; o 对不同模块的时钟增加开启和关闭功能,可以降低单片机的功耗 STM32为了低功耗,他将所有的外设时钟都设置为disable(不使能),用到什么外设,只要打开对应外设的时钟就可以, 其他的没用到的可以还是disable(不使能),这样耗能就会减少。 这就是为什么不管你配置什么功能都需要先打开对应的时钟的原因# q& Y/ l" c& M( @0 Q1 ?* S* ` STM32的时钟系统框图
/ i: a8 g: v- a% [9 [ % B" O: U r, T; u! M1 Y5 J 系统时钟SYSCLK 的右边,则是系统时钟通过AHB预分频器,给相对应的外设设置相对应的时钟频率 8 `! O; p3 C* W' Y5 T# w* f 从左到右可以简单理解为 各个时钟源--->系统时钟来源的设置--->各个外设时钟的设置 " n1 X2 H+ v. d$ F% S 时钟系统! J! c" U2 `% }3 o, H 1各个时钟源 (左边的部分)$ o/ Z: m. p* Z: _/ A STM32 有4个独立时钟源:HSI、HSE、LSI、LSE。) F/ {! N( Q# G% u2 @. R ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。1 b K$ E0 R0 Y ③、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。 ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。1 }/ Q6 a& v5 w# }) |) @, [7 Q' A $ a& h* y% ~/ F3 T& y 其中LSI是作为IWDGCLK(独立看门狗)时钟源和RTC时钟源 而独立使用 # p$ g+ E6 F5 D9 k4 e / y; Y# b# F& h1 e6 O 而HSI高速内部时钟 HSE高速外部时钟 PLL锁相环时钟 这三个经过分频或者倍频 作为系统时钟来使用) d4 f8 W' S: R. N5 N* F0 [0 i PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。 通过倍频之后作为系统时钟的时钟源 ) I' i7 ^) O' s6 J9 u' |- x 举个例子:Keil编写程序是默认的时钟为72Mhz,其实是这么来的:外部晶振(HSE)提供的8MHz(与电路板上的晶振的相关)通过PLLXTPRE分频器后,进入PLLSRC选择开关,进而通过PLLMUL锁相环进行倍频(x9)后,为系统提供72MHz的系统时钟(SYSCLK)。之后是AHB预分频器对时钟信号进行分频,然后为低速外设提供时钟。/ S: j) \) p3 l0 O4 S& Z ' M# X6 }( a# E& Q- y* ^ / a0 E+ T5 K m( `- Z0 N( W8 h. y6 s 或者内部RC振荡器(HSI) 为8MHz /2 为4MHz 进入PLLSRC选择开关,通过PLLMUL锁相环进行倍频(x18)后 为72MHz0 ?6 a, m( y/ n5 r$ l PS: 网上有很多人说是5个时钟源,这种说法有点问题,学习之后就会发现PLL并不是自己产生的时钟源,而是通过其他三个时钟源倍频得到的时钟 2系统时钟SYSCLK2 L, L/ ^" E5 D* h 系统时钟SYSCLK可来源于三个时钟源: ①、HSI振荡器时钟 ②、HSE振荡器时钟 ③、PLL时钟1 Q& R& _4 o* q H' m* ~: T# ? 最大为72Mhz
4把时钟信号输出到外部( P7 d! R* t( L: j, b+ l
5系统时钟通过AHB分频器给外设提供时钟(右边的部分) 重点9 k! g$ x) v4 M9 U : ]0 `: [, d+ b2 J+ [: y 从左到右可以简单理解为 系统时钟--->AHB分频器--->各个外设分频倍频器 ---> 外设时钟的设置 9 [* L% z( ]" ~6 V' O 右边部分为:系统时钟SYSCLK通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。其中AHB分频器输出的时钟送给5大模块使用: * T% g- L/ u" P5 C# M, m. ]5 v ①内核总线:送给AHB总线、内核、内存和DMA使用的HCLK时钟。 & x3 J" b2 ^; H }$ s ②Tick定时器:通过8分频后送给Cortex的系统定时器时钟。 8 j, O" F3 k2 {- Y1 F ③I2S总线:直接送给Cortex的空闲运行时钟FCLK。 5 Z4 v. t/ O5 @# Z& [: r Y, { ④APB1外设:送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给通用定时器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2-7使用。 * W- r8 w7 ^4 L; i3 {3 c ⑤APB2外设:送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给高级定时器。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用。6 W* U6 L1 [3 j7 B' V : d" e# ?2 ?( p% Q# _ 另外,APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。ADC分频器可选择为2、4、6、8分频。 ) }% H1 O3 a- o' a5 i 需要注意的是,如果 APB 预分频器分频系数是 1,则定时器时钟频率 (TIMxCLK) 为 PCLKx。否则,定 时器时钟频率将为 APB 域的频率的两倍:TIMxCLK = 2xPCLKx。 $ H7 x, O; I3 [0 q APB1和APB2的对应外设 F1系列
$ W# U; |4 l7 J' z - o) l, g @3 E/ D9 W' n 而APB2上面连接的是高速外设,包括UART1、SPI1、Timer1、ADC1、ADC2、ADC3、所有的普通I/O口(PA-PE)、第二功能I/O(AFIO)口等。 F4系列
/ `4 C( e. Q- _3 q# G) G( s! B' } % T9 x. \, V( ? APB2总线:高级定时器timer1, timer8以及通用定时器timer9, timer10, timer11 UTART1,USART6% X8 Y3 u: d1 b' [; M) g 8 \, d( o9 z6 N# O! m4 g APB1总线:通用定时器timer2~timer5,通用定时器timer12~timer14以及基本定时器timer6,timer7 UTART2~UTART5# d1 r7 M b9 } E 7 K$ G# [: }% [ - _" E, y# O0 F5 A$ z4 @ F4系列的系统时钟频率最高能到168M " r# m% U+ I( }% N' | # ]+ x! k7 v. g 具体 可以在 stm32f10x_rcc.h 和stm32f40x_rcc.h 中查看 , q/ Q3 l" `. ~ 或者通过 STM32参考手册搜索“系统架构”或者“系统结构” 查看外设挂在哪个时钟下,2 F8 c; i2 G2 {3 d3 B8 g : e2 I2 @ a( U/ {/ x# e RCC相关寄存器: 这里我们以F1系列为例 m4 L& d4 d; ]. o
可以对上上面的时钟框图和RCC寄存器来学习,对STM32的时钟系统有个大概的了解 其实也就是我们上面介绍的流程,理解了自然也就能写出来 " F& h2 f$ B6 W; @6 U4 D RCC初始化: 这里我们使用HSE(外部时钟),正常使用的时候也都是使用外部时钟 ! W, j' y0 Y1 r1 v4 Y, _$ j ! }' F* H! X& L 使用HSE时钟,程序设置时钟参数流程: 1、将RCC寄存器重新设置为默认值 RCC_DeInit; 2、打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON); 3、等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp(); 4、设置AHB时钟 RCC_HCLKConfig;: v6 l/ w! H- A% H# @ f, V% p 5、设置高速AHB时钟 RCC_PCLK2Config;5 l% ]/ q+ }+ j 6、设置低速速AHB时钟 RCC_PCLK1Config;1 h" G! O* I; N h, A. s 7、设置PLL RCC_PLLConfig;4 C' d L7 @6 [4 U% t* G 8、打开PLL RCC_PLLCmd(ENABLE); 9、等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) 10、设置系统时钟 RCC_SYSCLKConfig;5 O2 b) u y4 y$ ?/ k k 11、判断是否PLL是系统时钟 while(RCC_GetSYSCLKSource() != 0x08)3 Y7 C9 ?! h* ~5 B 12、打开要使用的外设时钟 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd() 代码实现:! H! o6 a6 E- K) T% R4 u 对RCC的配置函数(使用外部8MHz晶振) % ?% N4 D' ^* I6 d8 S: V1 E8 q- q! I6 T 1 l. N. i. O6 w5 B 系统时钟72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz TIMCLK=72M: S4 x- j! X4 Q, n7 r$ T1 ?+ q
5 w8 y) x$ ?. |9 O 时钟监视系统(CSS)3 r+ `; m T% e9 T2 r& r2 H$ ]
1 ]& A0 i$ ^( |1 D4 u$ y: w6 w - _* r v& H6 x; ^9 |; h |
经验分享 | 基于STM32G4芯片TIM+SPI+DMA应用示例
STM32G47x 双 Bank 模式下在线升级
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
低功耗蓝牙无线升级:STM32WB OTA 固件更新技术解析
STM32WB Zigbee 自定义集群开发实战:AN5491 应用笔记深度解读
【经验分享】STM32G4之基本定时器
NUCLEO-G474RE 扩展 LSM6DSO 传感器数据融合实操演示全解析
经验分享 | STM32G474 高精度定时器同步功能全解析 从内部互联到多芯片协同的实现方案
吃透:STM32WB 上 Zigbee 睡眠终端设备开发攻略
STM32 无线 MCU HSE 频率与启动时间精确调谐实战指南
微信公众号
手机版