本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发
向上代码兼容GD32F450ZGT6中使用
后续项目主要在下面该专栏中发布:
https://blog.csdn.net/qq_62316532/category_12608431.html?spm=1001.2014.3001.5482
感兴趣的点个关注收藏一下吧!
电机驱动开发可以跳转:
GD32F103RCT6/GD32F303RCT6-实战项目-无刷电机驱动(1)_gd32f103rct6例程-CSDN博客
BMS电源系统开发可以跳转:暂未放链接
介绍
今天我们又来对一期问题进行解答,太久没更新了,因为一直在忙着公司的出差,本次对串口通讯中出现的发送乱码问题进行解释。
首先需要排除的问题:
本篇文章,是针对于在串口常规配置都正确的情况下,依旧出现乱码的时候的教程
常规配置中可能导致串口发送出现乱码的问题:
1.检查波特率是否一致
2.检查串口数据格式是否正确
3.检查串口配置是否正确(引脚配置+串口配置+初始化)
4.检查是否在Main中对串口/延时函数/GPIO初始化
5.检查printf是否重定向
在排除以上常规问题后出现的串口乱码问题或者是从stm32移植到GD32中出现的乱码问题例如:
解决办法
1.乱码肯定是波特率出现问题
既然出现了乱码问题,在常规配置没有问题的情况下,我们就要去考虑,出现乱码问题的本质原因是什么呢?肯定是波特率始终对不上,但是明明我们设置的波特率比如9600,我们配置的时候写的就是9600呀?
这里就会有一个设计到串口时钟怎么去分频得到波特率的问题了
在STM32微控制器中,串行通信接口(如USART)的波特率是由串口时钟(USART_CLK)和USART_BRR寄存器中的设置共同决定的。USART_CLK通常来自于APB2或APB1总线时钟,这取决于USART的具体实例。例如,USART1通常连接到APB2总线上,而USART2至USART6则连接到APB1总线上。
stm32HAL库中配置例如:
// 设置USART时钟为84 MHz
__HAL_RCC_USARTx_CLK_ENABLE();
// 初始化USART配置结构体
huartx.Instance = USARTx;
huartx.Init.BaudRate = 115200;
huartx.Init.WordLength = UART_WORDLENGTH_8B;
huartx.Init.StopBits = UART_STOPBITS_1;
huartx.Init.Parity = UART_PARITY_NONE;
huartx.Init.Mode = UART_MODE_TX_RX;
huartx.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huartx.Init.OverSampling = UART_OVERSAMPLING_16;
// 初始化USART
HAL_UART_Init(&huartx);
2.如果是从stm32移植到GD32
在GD32系列微控制器中,串行通信接口(如USART)的波特率计算原理与STM32非常相似。GD32的USART模块同样通过分频其时钟源来产生所需的波特率。时钟源可以是APB2总线时钟,具体取决于所使用的USART模块。
但是GD32的主频拿标准的F1或者F303来说是108MHZ,比起stm32的主频72MHZ想比快上不少,那么可能一个配置不当就会产生波特率的问题。
那么说了这么多,我们该怎么去解决问题呢?
前面我们已经找到了问题是出现在波特率上面,那么自然而然,我们就需要去更改时钟晶振相关的配置了:
在GD32F450或者GD32F407中,我们能够找到外部晶振的宏定义,决定了外部输入晶振的大小,我之前出现乱码的原因是因为:之前这里内部是写的是25MHZ的晶振,但是我实际上焊接在板子外面的外部晶振却是8MHZ的晶振,那么我们就需要去修改宏定义的值了,如下图:
修改完毕以后就可以发现,串口发送到电脑端的数据又恢复正常了。
除了这里以外,在总时钟168MHZ的选取上,GD32内部也是提供了不同的选择:
该图是通过内部的16MHZ晶振以达到我们需要的200MHZ:
该图是启用外部时钟的8MHZ以达到我们需要的168MHZ的晶振:
注意事项
这里需要注意一个关联问题:在上图中我们能发现:同样是外部晶振输入,GD32预留了8MHZ、16MHZ、25MHZ的输入接口,那么我们在修改完宏定义后,记得在这里也进行相应的修改,不然就得不偿失了
上面讲的这些宏定义存在于:
这两个文件中!
王炸解决办法
如果对于精度不那么重要的场合,可以选择内部自带的芯片晶振去启动芯片,这样就可以解决绝大多数的乱码问题啦!