0x00 前言
写下这篇文章的主要目的是总结一下关于最近调试一块单板遇到的,关于串口方面的一些问题。本文将会分为上下两篇,这篇主要讲述的是:
串口在发送数据时莫名其妙的出现不可预知的错误
阅读本文,您可能需要准备的一些知识有:
知识名称 | 熟练度 |
---|---|
串口协议波形 | 了解 |
数字电路 | 基础 |
C语言 | 基本 |
0x01 问题出现
当我使用一块单板进行收发数据时,在发送指定数据0x55和0xAA时,接收端竟然莫名其妙的收到了C0、FE、FF等错误。而且错误位置不固定,错误接收也不固定。
0x02 问题排查
一般来说,整个串行总线的数据流都是一条直线,因此我就在这条直线上的各个设备两端并入我的测试设备或测试方法,以达到成功找到问题的目的。
在排查了数据线和上位机接收端的数据错误的可能之后(这个问题我会在下文详细说明),随即针对单板串口发送段进行数据的检测。
上位机和单板之间的波特率配比皆为115200,通过示波器观察波形可以看出。在发送报文期间,示波器也出现了正常的波形图。但是仔细观察可以发现,这个时候的波形整体时长其实是不对的,正常的波形应该要有1000ms/115200 = 8μs
左右。也就是说,在8μs的时候,就会发完一个完整的数据帧。每个数据帧根据当前的数据格式定义分为10个波形、11个波形、12个波形。但是他竟然花费了较长时间(约为Π倍),也就是将近25μs才传输完。
随后我第一时间想到了当前的时钟系统是否出现了一些问题……于是打开了官方神器:STM32CubeMX,从中可以看出,当前的默认配置是根据默认的25MHz的情况下配置的,也就是说,当前的PLL_M为25。但是项目单板使用的晶振则是8MHz的,就会导致整个时间都会被延长约3.22倍。也就会影响到当前的波形的发送。
于是我打开System_stm32f2xx.h,将#define PLL_M 25
改为#define PLL_M 8
,这个宏定义会将其硬件时钟系统定位为最高的120MHz,也就对应了当前的单片机最高的时钟系统。
** PS: 虽然上面的时钟树规定了当前的PLL_Q为4,不能将数据修改。但是当前的代码宏定义中却将PLL_Q定义成了5,这样就可以将USB clock修改成48MHz **
但是在重新刷写之后,还是没有解决这个问题。而且当前的波形完全错乱了,整个波形完全都不是正常的波形。
大概就是这个样子,数据的格式也都不对。也就完全不可能去完成数据的接收。
这个波形的出现让我花费了十分长的时间去查找原因,最后终于发现了具体的原因。
void send()
{
USART_SendData(USART1,0x55);
USART_SendData(USART1,0xAA);
}
这两个函数看起来似乎没什么问题,但是细细想来则会发现,一组波形大约需要1/115200=0.00000868s≈8.68μs
,但是执行指令执行大概只会花费50ns左右。于是先前的数据还没有发送完成就会被新的数据覆盖。就会出现当前的这个问题。
0x03 排查的小绊脚石
找到这个原因之前,我发现,可能因为某些宏定义冲突或者参数影响。则会导致当前的数据出现及其不稳定的故障,可以直接将编译宏定义中的USE_STM322xG_EVAL与OTGXX
的两个宏定义去掉即可。
更多
本文首发自 记:一次单板的意外串口异常解决(上)——下位机端。-我的博客,更多文章可进入我的博客详查。