STM32F4x系列时钟树如下:
1、系统时钟SYSCLK
在STM32F407中,除了一些特定的时钟(例如,USB OTG FS时钟,I2S时钟)外,系统所有外设的时钟均是通过SYSCLK来提供的。也就是说我们经常用到的外设时钟,都是通过SYSCLK分频得到的。下面是和SYSCLK相关的时钟树的图。
由图中可以看到,SYSCLK的来源主要有三个。
- HSI 振荡器时钟
- HSE 振荡器时钟
- 主 PLL (PLL) 时钟
下面分别来看下系统时钟SYSCLK的三个来源。
(1) 高速外部时钟HSE(4M~26M)
高速外部时钟是芯片内部的HSE振荡器产生的。高速外部信号(HSE)有两个时钟源。
- HSE外部晶振/陶瓷振荡器
- HSE外部用户时钟
下图是HSE/LSE的时钟源硬件配置
外部晶振/陶瓷振荡器( HSE晶振)
这种方式是通过在OSC_IN和OSC_OUT接入外部晶振实现的。在这种模式下,因为晶振起振需要一定的时间,因此可以通过RCC 时钟控制寄存器(RCC_CR) 中的HSERDY 标志指示高速外部振荡器是否稳定。时钟启动后,HSERDY被硬件置1。如果在RCC时钟中断寄存器(RCC_CIR)中使能中断,则可以触发中断。
HSE晶振可以通过RCC时钟控制寄存器(RCC_CR)的HSEON打开或者关闭。
HSE外部时钟源(HSE旁路)
这种方式是指通过OSC_IN引脚输入一个外部时钟源,这个时钟源是外部产生的现成的时钟信号。在这种模式下,必须使用占空比大约为50%的外部时钟信号来驱动OSC_IN引脚。
此模式通过RCC时钟控制寄存器(RCC_CR)的HSEBYP和HSEON位一起置1进行选择。
注意:
RCC-》CR |= ((uint32_t)RCC_CR_HSEON|RCC_CR_HSEBYP)此时选择的是HSE旁路,如果HSE是HSE晶振,则晶振启动不了,时钟源会默认选择HSI。
RCC-》CR |= ((uint32_t)RCC_CR_HSEON)此时选择HSE晶振。
HSE外部晶振频率在stm32f4xx.h里的HSE_VALUE更改。
(2) 高速内部时钟HSI
STM32F407内部自带一个16M的内部晶振,这个晶振产生的时钟信号可以直接用作系统时钟SYSCLK。也可以作为PLL的输入。内部晶振的优点是成本低,启动速度也比外部晶振要快,但是内部晶振的精度比外部晶振要差。可以通过RCC时钟控制寄存器(RCC_CR)中的HSIRDY 标志来判断HSI RC时钟信号是否稳定。
(3) 主PLL时钟
STM32F407具有两个PLL,用于产生不同的时钟信号。这里主要来讨论主PLL时钟。主PLL时钟的时钟源有两个信号,分别是上边提到的HSI信号和HSE信号。PLL通过把这两个信号倍频,分频等达到更高频率的时钟信号。一般来说,由于HSI和HSE的时钟频率较低,SYSCLK一般都不会选择HSI时钟和HSE时钟作为系统时钟,而主PLL产生的时钟一般会用作系统时钟。(但是,我刚接手的项目工程确实用了HSI作为系统时钟,搞了一天,最后还是借用RCC_GetClocksFreq(&get_rcc_clock) 这个函数查看实时时钟才发现问题,怪我太蠢。)下面是主PLL的内部结构框图。
由图可以看出PLL的时钟源主要有两个:HSE时钟信号和HIS时钟信号。其中PLL_M,PLL_N,PLL_P,PLL_Q是一个分频器,而PLL_M是一个倍频器。假设图中经过PLL_N之后的时钟信号为PLL_VCO,PLL使用外部时钟信号HSE作为时钟源。那么有如下关系。
锁相环压腔振荡器时钟PLL_VCO = (HSE / PLL_M)* PLL_N
系统时钟SYSCLK = PLL_VCO/ PLL_P
所以,如果外部晶振的频率已经确定了,那么确定PLL_M,PLL_N,PLL_P的系数就可以得到对应频率的系统时钟SYSCLK,其中PLL_M,PLL_N,PLL_P可以有多种组合,只要满足相应的条件即可。例如,假设外部晶振为8M,对STM32F407来说,系统时钟的最大频率为168M,那么久可以分别设置PLL_M = 8,PLL_N = 336,PLL_P = 2。来产生168M的时钟。即SYSCLK = ( 8 /8 ) * 336 / 2 = 168M。
通过配置主PLL,我们就得到了系统的主时钟SYSCLK,下一步我们就可以通过这个时钟来分频得到各个外设的时钟。
2、AHBx时钟
经过AHBx预分频器,可以得到AHBx外设时钟。一般来说AHBx分频器的值为1,也就是说AHBx的时钟和系统时钟相等。AHBx上边所挂的外设可以到RCC和AHBx外设相关的寄存器去看,在使能AHBx上的某个外设之前,必须使能该外设时钟。
3、APB1和APB2时钟
经过APB1预分频器和APB2预分频器可以得到APB1和APB2外设时钟。在STM32F407里边,APB1的最大时钟为42M,APB2的最大时钟为84M。同样可以在RCC的寄存器下边观测APB1和APB2上边所挂的外设。使用某个外设之前也要使能相应的时钟。
由上图可知,APB1和APB2是由AHBx分频得到。分频在system_stm32f4xx.c里的SetSysClock()里实现。
STM32F4x系列时钟树如下:
1、系统时钟SYSCLK
在STM32F407中,除了一些特定的时钟(例如,USB OTG FS时钟,I2S时钟)外,系统所有外设的时钟均是通过SYSCLK来提供的。也就是说我们经常用到的外设时钟,都是通过SYSCLK分频得到的。下面是和SYSCLK相关的时钟树的图。
由图中可以看到,SYSCLK的来源主要有三个。
- HSI 振荡器时钟
- HSE 振荡器时钟
- 主 PLL (PLL) 时钟
下面分别来看下系统时钟SYSCLK的三个来源。
(1) 高速外部时钟HSE(4M~26M)
高速外部时钟是芯片内部的HSE振荡器产生的。高速外部信号(HSE)有两个时钟源。
- HSE外部晶振/陶瓷振荡器
- HSE外部用户时钟
下图是HSE/LSE的时钟源硬件配置
外部晶振/陶瓷振荡器( HSE晶振)
这种方式是通过在OSC_IN和OSC_OUT接入外部晶振实现的。在这种模式下,因为晶振起振需要一定的时间,因此可以通过RCC 时钟控制寄存器(RCC_CR) 中的HSERDY 标志指示高速外部振荡器是否稳定。时钟启动后,HSERDY被硬件置1。如果在RCC时钟中断寄存器(RCC_CIR)中使能中断,则可以触发中断。
HSE晶振可以通过RCC时钟控制寄存器(RCC_CR)的HSEON打开或者关闭。
HSE外部时钟源(HSE旁路)
这种方式是指通过OSC_IN引脚输入一个外部时钟源,这个时钟源是外部产生的现成的时钟信号。在这种模式下,必须使用占空比大约为50%的外部时钟信号来驱动OSC_IN引脚。
此模式通过RCC时钟控制寄存器(RCC_CR)的HSEBYP和HSEON位一起置1进行选择。
注意:
RCC-》CR |= ((uint32_t)RCC_CR_HSEON|RCC_CR_HSEBYP)此时选择的是HSE旁路,如果HSE是HSE晶振,则晶振启动不了,时钟源会默认选择HSI。
RCC-》CR |= ((uint32_t)RCC_CR_HSEON)此时选择HSE晶振。
HSE外部晶振频率在stm32f4xx.h里的HSE_VALUE更改。
(2) 高速内部时钟HSI
STM32F407内部自带一个16M的内部晶振,这个晶振产生的时钟信号可以直接用作系统时钟SYSCLK。也可以作为PLL的输入。内部晶振的优点是成本低,启动速度也比外部晶振要快,但是内部晶振的精度比外部晶振要差。可以通过RCC时钟控制寄存器(RCC_CR)中的HSIRDY 标志来判断HSI RC时钟信号是否稳定。
(3) 主PLL时钟
STM32F407具有两个PLL,用于产生不同的时钟信号。这里主要来讨论主PLL时钟。主PLL时钟的时钟源有两个信号,分别是上边提到的HSI信号和HSE信号。PLL通过把这两个信号倍频,分频等达到更高频率的时钟信号。一般来说,由于HSI和HSE的时钟频率较低,SYSCLK一般都不会选择HSI时钟和HSE时钟作为系统时钟,而主PLL产生的时钟一般会用作系统时钟。(但是,我刚接手的项目工程确实用了HSI作为系统时钟,搞了一天,最后还是借用RCC_GetClocksFreq(&get_rcc_clock) 这个函数查看实时时钟才发现问题,怪我太蠢。)下面是主PLL的内部结构框图。
由图可以看出PLL的时钟源主要有两个:HSE时钟信号和HIS时钟信号。其中PLL_M,PLL_N,PLL_P,PLL_Q是一个分频器,而PLL_M是一个倍频器。假设图中经过PLL_N之后的时钟信号为PLL_VCO,PLL使用外部时钟信号HSE作为时钟源。那么有如下关系。
锁相环压腔振荡器时钟PLL_VCO = (HSE / PLL_M)* PLL_N
系统时钟SYSCLK = PLL_VCO/ PLL_P
所以,如果外部晶振的频率已经确定了,那么确定PLL_M,PLL_N,PLL_P的系数就可以得到对应频率的系统时钟SYSCLK,其中PLL_M,PLL_N,PLL_P可以有多种组合,只要满足相应的条件即可。例如,假设外部晶振为8M,对STM32F407来说,系统时钟的最大频率为168M,那么久可以分别设置PLL_M = 8,PLL_N = 336,PLL_P = 2。来产生168M的时钟。即SYSCLK = ( 8 /8 ) * 336 / 2 = 168M。
通过配置主PLL,我们就得到了系统的主时钟SYSCLK,下一步我们就可以通过这个时钟来分频得到各个外设的时钟。
2、AHBx时钟
经过AHBx预分频器,可以得到AHBx外设时钟。一般来说AHBx分频器的值为1,也就是说AHBx的时钟和系统时钟相等。AHBx上边所挂的外设可以到RCC和AHBx外设相关的寄存器去看,在使能AHBx上的某个外设之前,必须使能该外设时钟。
3、APB1和APB2时钟
经过APB1预分频器和APB2预分频器可以得到APB1和APB2外设时钟。在STM32F407里边,APB1的最大时钟为42M,APB2的最大时钟为84M。同样可以在RCC的寄存器下边观测APB1和APB2上边所挂的外设。使用某个外设之前也要使能相应的时钟。
由上图可知,APB1和APB2是由AHBx分频得到。分频在system_stm32f4xx.c里的SetSysClock()里实现。
举报