在上篇博客中介绍了如何配置STM32F407VET6标准库并移植FreeRTOS。在我后续配置定时器输出PWM波时,发现频率不对,后来发现时钟树没有配对,这里记录一下如何配置时钟树。
这里先发两张更改前后的示波器测量对比图:
测量前:期望频率是1KHz,实测为857.15Hz
测量前:期望频率是1KHz,实测为1KHz
一、更改外部晶振频率
在stm32f4xx.h中,更改如下代码:
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || \
defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F469_479xx)
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
我们用的是STM32F407系列,所以条件编译这里选择以下
#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || \defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F469_479xx)
我们板子上如果加了外部晶振的话,将HSE_VALUE改成外部晶振频率,我这里是8M,所以我改成8000000
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
二、更改锁相环配置
在system_stm32f4xx.c文件中大概147行开始,将锁相环配置改为如下数值
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 8
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
/******************************************************************************/
其中:
-
PLL_M:这个值用于将输入时钟(HSE_VALUE 或 HSI_VALUE)分频,以得到PLL的输入频率。对于STM32F407系列,HSE通常为外部晶振频率(例如8 MHz),而HSI为内部时钟频率(16 MHz)。分频后的频率应该在1到2 MHz之间。
-
PLL_N:这个值用于将分频后的PLL输入频率乘以一个倍数,从而得到更高的频率,称为PLL VCO(压控振荡器)频率。这个频率范围通常在100到432 MHz之间。
-
PLL_P:这个值用于将PLL VCO频率再次分频,以得到系统时钟(SYSCLK)。系统时钟是微控制器运行的主时钟源。可能的值为2、4、6、或8。
-
PLL_Q:这个值用于将PLL VCO频率分频,以得到USB OTG FS、SDIO和随机数发生器(RNG)的时钟。对于USB,通常需要设置为48 MHz,因此需要合适地选择PLL_N和PLL_Q以确保这一点。
-
这里举例,配置系统时钟配168MHz
- 输入频率:8 MHz(HSE)
- PLL_M:8
- 输入频率分频:8 MHz / 8 = 1 MHz
- PLL_N:336
- VCO频率:1 MHz * 336 = 336 MHz
- PLL_P:2
- 系统时钟(SYSCLK):336 MHz / 2 = 168 MHz
- PLL_Q:7
- USB、SDIO、RNG时钟:336 MHz / 7 ≈ 48 MHz
在这种配置下,系统时钟被配置为168 MHz,USB等外设时钟约为48 MHz,满足USB的时钟要求。
最后放一张STM32CubeMAX的时钟树进行比对