遇到的问题:
同样的串口配置代码在一种407开发板上能正常输出,但是换到另一种407开发板上后就出现乱码,检查串口输出波形后发现,电平转换芯片没有问题,但是波特率却有问题。
问题原因:
经过故障排查发现出现上述问题的原因是两种STM32F407使用的外部晶振的频率不一样,前者使用的是25MHZ的晶振,而后者却是使用的8MHZ的晶振,如果代码未经更改而直接用在后者身上,就会出现上述串口乱码的情况,而且后者的每bite位的周期就是前者的三倍左右。
解决办法:
方法一:
因为 STM32F407的库文件中默认晶振值为25MHz,若外接晶振8MHz。所以:
1.首先需要修改"Option for target 'xxx'"中的Target -> Xtal(Mhz)处的值(改为8MHz)。此处修改影响Debug时观察到的时钟数值。
2.stm32f4xx.h默认25M外部晶振(HSE):
#if !defined (HSE_VALUE)
#defineHSE_VALUE ((uint32_t)25000000) /*!<Value of the External oscillator in Hz25000000 */
#endif /* HSE_VALUE*/
如果改为8M或其他值,需要修改此宏定义。
为了尽量保持官方固件库的完整性,可在stm32f4xx_conf.h中添加代码
#if defined (HSE_VALUE)
/* Redefine the HSE value;it's equal to 8 MHz on the STM32F4-DISCOVERY Kit*/
#undef HSE_VALUE
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
注:但PLL_M定义在system_stm32f4xx.c中的,此方法对其不可用,亲测。
3. 打开文件 "system_stm32f4xx.c" ,搜索”PLL_M",修改默认PLL_M的参数:
/*************************PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUEor HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
#define PLL_N 336
/* SYSCLK = PLL_VCO /PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO andRNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
/******************************************************************************/
同样改为8M的话,PLL_M也应该改为8.(假设最后的时钟值不变)。
PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N =
25/25*336 = 336M (8/8*336=336M)
SYSCLK = PLL_VCO / PLL_P =
336 / 2 = 168M 默认是168M时钟。
方法二:(目前找到的最好解决方法,若有更好的方法,欢迎前来交流)
1.首先需要修改"Option for target 'xxx'"中的Target -> Xtal(Mhz)处的值(改为12MHz)。此处修改影响Debug时观察到的时钟数值。
2. 在"Option for target 'xxx'"中的C/C++-> Define处添加
HSE_VALUE=8000000, 宏
在这里修改HSE的值,然后依然要修改"system_stm32f4xx.c"文件中的PLL_M,否则,在115200以上波特率下,首字节字符是乱码。亲测。(修改stm32f4xx.h里面的值不是不可以,但是感觉修改里面的东西不是很好,毕竟都是库来的,以后调用的时候也不用想着这个问题。但是,现在尚未找到更好的解决办法)
3. 打开文件 "system_stm32f4xx.c" ,搜索”PLL_M",修改默认PLL_M的参数:
/*************************PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUEor HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
#define PLL_N 336
/* SYSCLK = PLL_VCO /PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO andRNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
/******************************************************************************/