时钟树
本文主要从STM32F1平台出发,介绍时钟树的概念,结合时钟树的框图,详细讲解时钟树的基本原理和配置过程。
你可能会有的疑惑?
MCU的时钟树是跟着ARM的Cortex-M4架构走,还是跟着ST的F4系列走?
简单说,每款MCU的时钟树,都是芯片厂商为其“量身定制”的。ARM架构只是定义了内核需要哪些时钟信号以及如何与它们接口。而具体的时钟树配置,是由芯片厂商(ST)根据其具体的硬件资源和性能需求,进行定制的。
什么是时钟树?
MCU内部有许多外设,这些外设需要不同的时钟信号来工作。而我们的晶振只能产生单一频率的主时钟信号,
为了满足这些外设的不同时钟需求,我们需要对这个主时钟信号进行分频、倍频或相位调整,生成不同频率的时钟信号,供给不同的外设使用。最终各个时钟线呈现出来的结构就像一棵树一样,所以被称为时钟树。
时钟源

从图片可以看出来,STM32F4中有5个最重要的时钟源,为HSI、HSE、LSI、LSE、PLL。
其中PLL实际是分为两个时钟源,分别为主PLL和专用PLL。 讲解顺序是按图中蓝圈标示的顺序。
命名规则为:L代表Low,H代表High,S代表Speed,I代表Internal,E代表External。
LSI内部低速时钟
RC振荡器,频率为32kHz左右。供独立看门狗和自动唤醒单元使用。
LSE外部低速时钟
接频率为32.768kHz的石英晶体,这个主要是RTC的时钟源。
HSE外部高速时钟
可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz。HSE可以直接作为系统时钟或者PLL的输入。
HSI内部高速时钟
RC振荡器,频率为16MHz。可以直接作为系统时钟或者用作PLL输入。
PLL锁相环倍频输出
STM32F4有两个PLL:
- 主PLL(PLL)由HSE或者HSI提供时钟信号,并具有两个不同的输出时钟。
- 第一个输出PLLP用于生成高速的系统时钟(最高168MHz)。
- 第二个输出PLLQ用于生成USB OTG FS的时钟(48MHz),随机数发生器的时钟和SDIO时钟。
- 专用PLL(PLLI2S)用于生成精确时钟,从而在I2S接口实现高品质音频性能。
这里我们着重看看主PLL时钟第一个高速时钟输出PLLP的计算方法。
- 大概分析:主PLL的输入先经过一个分频系数为M的分频器成为了VCO的时钟输入,
(VCO是PLL的一部分,压控振荡器),然后再经过倍频系数为N的倍频器,
最后再经过一个分频系数为P(系统时钟的)或者Q(外设时钟)的分频器之后才生成主PLL时钟。 - 举例分析:
(1)假设HSE = 8MHZ,我们选择了HSE作为PLL的时钟源,因为VCO的时钟必须要在1-2M之间,所以我们设置PLL_M = 8M,得到PLL_VCO = 1M.
(2)接着VCO输入时钟经过VCO倍频因子N倍频之后,成为了VCO的时钟输出,VCO时钟必须在192-432M之间,我们配置N = 336,则VCO时钟输出为336M,VCO时钟输出后有3个分频因子。
- PLLCLK 分频因子 P
- 时钟分频因子 Q
- 分频因子 R(F446 才有,F407 没有)。
- 有关 PLL 的配置有一个专门的 RCC PLL 配置寄存器RCC_PLLCFGR,具体描述看手册即可。
VCOCLK_IN = PLLCLK_IN / M = HSE / 8 = 1M |
上面提到的系统时钟
系统时钟是MCU的主要时钟源,它提供给所有的外设。系统时钟来源可以是:HSI、PLLCLK、HSE,具体的由时钟配置寄存器RCC_CFGR 的SW位配置。
我们这里设置系统时钟:SYSCLK = PLLCLK = 168M。如果系统时钟是由 HSE 经过 PLL 倍频之后的 PLLCLK 得到,当 HSE 出现故障的时候,系统时钟会切换为 HSI=16M,直到 HSE 恢复正常为止。
AHB总线时钟HCLK
系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 AHB 总线时钟,即 HCLK。
分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器 RCC_CFGR的HPRE位设置。
片上大部分外设的时钟都是经过 HCLK 分频得到,至于 AHB 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需设置好 APB 的时钟即可。我们这里设置为 1 分频,即 HCLK=SYSCLK=168M。
APB2总线时钟PCLK2
APB2 总线时钟 PCLK2 由 HCLK 经过高速 APB2 预分频器得到。
分频因子可以 是:[1,2,4,8,16],具体由时钟配置寄存器RCC_CFGR的PPRE2位设置。
HCLK2 属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的 GPIO、USART1、SPI1 等。
至于 APB2 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置。
我们这里只需设置好 APB2 的时钟即可。我们这里设置为2分频,即PCLK2 = HCLK /2= 84M。
APB总线时钟PCLK1
APB1 总线时钟 PCLK1 由 HCLK 经过低速 APB 预分频器得到,分频因子可以是:[1,2,4,8,16]
具体由时钟配置寄存器RCC_CFGR的PPRE1位设置。
HCLK1 属于低速的总线时钟,最高为 42M,片上低速的外设就挂载到这条总线上。
比如 USART2/3/4/5、SPI2/3,I2C1/2 等。
至于 APB1 总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置。
我们这里只需设置好 APB1 的时钟即可。我们这里设置为4分频,即PCLK1 = HCLK/4 = 42M。
APBx定时器时钟
这个配置定时器的时候,需要特别注意
当APBx分频数为1的时候,对应定时器的时钟为APBx的时钟,否则对应定时器时钟都是APB总线的两倍。
SystemInit函数
在启动文件中,有一个名为 SystemInit 的函数,它是在单片机启动时被调用的。
这个函数的主要作用是初始化系统时钟,设置系统时钟源、分频器和倍频器。
在 SystemInit 函数中,我们可以个性化地配置系统时钟为我们需要的频率。
