【STM32教程】解决串口通信乱码问题及系统时钟来源详解
使用 stm32f407 与电脑主机进行串口通信时,串口助手打印乱码,主要从以下方面进行排查:
最终发现是外部晶振频率和库函数不一致的问题。
一、时钟分析
1、认识时钟源
我们要检查的是 APB2总线的时钟源是否设置正常,因为我们当前使用的串口 USART1 与 APB2 总线(高速总线)相连,从下图看,时钟源有三个:
就结果而言,选择的时钟源是 PLLCLK。(若想了解,可以参考最后一部分)
2、计算系统时钟
现在已经知道了选择的是 PLLCLK 作为时钟源,那么我们就可以顺着这条路线计算系统时钟的值。正点原子 stm32f407 的外设时钟频率 HSE = 8 M
① 输入 HSE
② 经过 M 分频,得到的结果为 HSE / M = 8 / M
③ ④ ⑤ ⑥ 经过 N 倍频,VCO的输出为 (HSE / M ) * N
⑦ 再次 P 分频就得到 SYSCLK = (HSE / M ) * N / P
二、解决外部晶振频率和库函数不一致的问题
从上面可知,选择的系统时钟频率 SYSCLK = (HSE / M ) * N / P,配置文件预期的 SYSCLK = 144MHz,其余参数也都指定了
实际上 HSE 需要视开发板具体情况而定,stm32f4 的 HSE 为 8 MHz,然而配置文件中配置的频率是 25 M,为了不影响原本的SYSCLK,我们需要修改 HSE 和 PLL_M。
1、修改 HSE
HSE 在程序中的体现为宏定义 HSE_VALUE ,该宏定义在 stm32f4xx.h 文件中
这里有两种修改方法,可任选一种修改
2、修改 PLL_M
分频数 M 在程序中的体现是宏定义 PLL_M,该宏定义在 system_stm32f4xx.c 文件中
三、为什么可以确定时钟源为 PLLCLK 而不是 HSE
stm32 在启动的时候就会调用 SystemInit 函数,这个函数就包含了初始化外设的时钟源。这个函数定义在 system_stm32f4xx.c 中。我们直接找到 SetSysClock 函数,这之前的都是将控制寄存器位清零的操作。
我们进入到 SetSysClock 函数,首先是HSE使能,等待时钟准备就绪。刚上电的时候 HSE 晶振不稳定,需要等待 6 个晶振时钟周期。
PLL 使能,等待时钟准备就绪。一开始 PLL 处于被锁定状态,这里需要等待 PLL 解锁。
一切准备就绪,然后将 PLL 设为系统时钟。
参考文章:
在串口通信实验中出现通信乱码怎么办-电子发烧友网 (elecfans.com)
作者:仲夏夜之梦~