STM32F0xx标准库使用16MHz晶振出现串口乱码问题

关键字:stm32、标准库、16m、晶振、串口、乱码
时间:2020年4月

问题

STM32F030是48MHz主频,标准库STM32F0xx_StdPeriph_Driver的相关代码默认外部晶振为8MHz。通常可以通过定义HSE_VALUE宏,来修改晶振频率。但是只修改HSE_VALUE为16M,主频则变成了96MHz,MCU处于超频状态运行,不能长期运行,并且会影响串口、SPI、I2C等外设的正常运行。

解决方法

修改PREDIV和PLLMUL两个寄存器,从而使主频(SYSCLK)回到正常的48MHz。原理参考STM32F030F4数据手册“clocks and startup”章节。

stm32f0xx.h文件

修改前

...
#if !defined  (HSE_VALUE)     
#define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz*/
#endif /* HSE_VALUE */
...

修改后

...
#if !defined  (HSE_VALUE)     
#define HSE_VALUE    ((uint32_t)16000000) /*!< Value of the External oscillator in Hz*/
#endif /* HSE_VALUE */
...

system_stm32f0xx.c文件

修改前

...
static void SetSysClock(void)
{
  ...
    /* PLL configuration */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
  ...
}
...

修改后

...
static void SetSysClock(void)
{
  ...
    /* PLL configuration */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6);
  ...
}
...

或者修改后

...
static void SetSysClock(void)
{
  ...
    /* PLL configuration */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL3);
  ...
}
...