STM32串口打印输出乱码的解决办法

作者试用uFUN开发板时,调用串口printf调试功能输出乱码,发现是外部晶振频率与固件库参数不一致导致。文章介绍了解决方法,一是修改stm32f10x.h文件中的晶振频率,二是修改system_stm32f10x.c文件中的倍频系数,此方法仅针对晶振改变导致的乱码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在试用uFUN开发板,下载配套的Demo程序,串口数据输出正常,当使用另一个模板工程,调用串口printf调试功能时,输出的却是乱码,最后发现是外部晶振频率不一样。很多STM32开发板都是使用的8M晶振,这个也是ST官方推荐的晶振频率,而且固件库默认是8M频率,倍频系数9。而uFUN开发板的晶振是和CH340共用一个12M晶振。如果固件库的参数不和硬件实际连接的晶振频率一致,那么不仅是串口会出现乱码,而且定时器这些也是不准确的,因为基本的工作时钟被打乱了。其实之前也遇到过这个问题,这次就算是记录一下吧!

1.修改stm32f10x.h文件中的晶振频率

打开工程中的stm32f10x.h文件,Ctrl+G快捷键定位到119行,把宏定义

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

外部晶振频率8M修改为12M

#define HSE_VALUE    ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */

如下图所示:

2.修改system_stm32f10x.c文件中的倍频系数

打开工程中的system_stm32f10x.c文件,Ctrl+G快捷键定位到1056行,把宏定义

RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

倍频系数由9修改为6,因为STM32F103主频最高到72MHz,外部晶振改为12M后,所以倍频系数改为6

RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6);

如下图所示:

总结

当然串口乱码可能不止这一个原因,这个解决方法只针对于外部晶振的改变,导致的串口数据乱码。其他问题还要仔细分析,总得来说,两个问题:程序问题,硬件问题。

参考资料:


历史精选文章:


欢迎大家关注我的个人博客

或微信扫码关注我的公众号

<think>好的,用户遇到了STM32F4串口输出乱码的问题,需要解决方案。首先,我需要回忆一下常见的串口问题原因,并结合提供的引用内容来分析可能的原因。 根据引用[1]、[2]、[3],问题主要集中在时钟配置,尤其是晶振频率设置不正确。用户可能使用STM32CubeMX配置时,默认的HSE_VALUE与实际硬件晶振不符,导致串口波特率计算错误,从而出现乱码。 接下来,我需要按照步骤来排查问题。首先检查波特率是否匹配,确认两边设备设置的波特率一致。然后检查中断配置是否正确,比如是否有使能中断或者中断优先级冲突。但根据引用内容,用户已经排除了前两个原因,所以重点可能在时钟配置。 然后,检查外部晶振频率设置是否正确。用户可能使用的是25MHz晶振,但代码中HSE_VALUE可能仍设置为默认的8MHz或16MHz,这会导致系统时钟和串口波特率计算错误。需要修改HSE_VALUE的定义,通常在stm32f4xx_hal_conf.h或类似的配置文件中。 此外,还需要检查系统时钟配置函数,确保PLL的分频系数正确,比如RCC_OscInitStruct.PLL.PLLM的值是否与实际晶振频率匹配。例如,如果晶振是25MHz,PLLM可能需要设置为25,这样HSE_VALUE和PLLM一致,系统时钟才能正确计算。 最后,验证时钟配置是否成功,可以通过测量系统时钟或使用示波器检查串口波特率是否正确。如果没有设备,可以输出固定数据测试是否仍有乱码。 总结解决方案步骤:检查波特率,检查中断,修正HSE_VALUE和PLL配置,验证时钟。确保所有配置与实际硬件一致,特别是晶振频率。</think>### STM32F4串口输出乱码解决方案 **问题原因分析** STM32F4串口输出乱码通常由以下原因导致: 1. **波特率不匹配**:发送端与接收端设置的波特率不一致[^2] 2. **时钟配置错误**:外部晶振频率(HSE)与代码中的配置值不匹配,导致系统时钟和串口时钟分频错误[^1][^3] 3. **中断配置异常**:串口中断未正确启用或优先级冲突[^2] --- #### **逐步解决方案** **1. 检查波特率配置** - 确认发送端(STM32)与接收端(如PC串口助手)的波特率完全一致 - 使用公式验证波特率计算: $$ \text{USARTDIV} = \frac{f_{\text{CLK}}}{16 \times \text{BaudRate}} $$ 其中 $f_{\text{CLK}}$ 为串口时钟频率(来自APB总线) **2. 修正时钟配置(关键步骤)** - **步骤1**:在代码中定位 `stm32f4xx_hal_conf.h` 文件,修改 `HSE_VALUE` 定义: ```c #define HSE_VALUE ((uint32_t)25000000) // 若硬件使用25MHz晶振 ``` - **步骤2**:检查 `SystemClock_Config()` 函数中的PLL配置,确保分频系数与晶振匹配: ```c RCC_OscInitStruct.PLL.PLLM = 25; // 当HSE=25MHz时,PLLM分频系数设为25 ``` 需满足关系: $$ f_{\text{PLL输入}} = \frac{HSE\_VALUE}{PLLM} $$ **3. 验证系统时钟** - 在 `main()` 函数初始化后添加以下代码,输出系统时钟频率: ```c printf("System Clock: %ld Hz\n", HAL_RCC_GetSysClockFreq()); ``` - 若输出值与预期不符(如应为180MHz但显示错误),则需重新检查PLL配置 **4. 排查中断问题** - 确认已启用USART全局中断: ```c HAL_NVIC_EnableIRQ(USARTx_IRQn); HAL_NVIC_SetPriority(USARTx_IRQn, 0, 0); ``` - 检查是否因中断嵌套导致数据丢失 --- #### **代码修改示例** 以STM32CubeMX生成代码为基础: 1. 修改 `Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_conf.h`: ```c #define HSE_VALUE 25000000 // 原默认为8000000 ``` 2. 更新 `SystemClock_Config()` 中的PLL参数: ```c RCC_OscInitStruct.PLL.PLLM = 25; // 原可能为8或16 RCC_OscInitStruct.PLL.PLLN = 360; // 确保最终PLL输出为180MHz ``` --- #### **验证方法** 1. 使用示波器测量USART_TX引脚波形,验证实际波特率 2. 发送连续字符 `AA 55`(二进制交替信号),观察波形是否对称 3. 若使用printf重定向,可发送固定字符串测试乱码规律[^2] ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

whik1194

如果对你有帮助,欢迎打赏。谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值