IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32串口自定义数据接收协议 -> 正文阅读

[嵌入式]STM32串口自定义数据接收协议

写在前面

最近使用STM32做串口数据收发,遇到了一些问题。折腾了一番,在此记录一下。

0 需求

  1. 云平台通过“发布消息”,下行指令。
  2. 4G模块接收平台下行指令并转发到单片机,单片机通过串口(UART3)做数据接收与分析。
    总的来说,比较简单。单片机和4G通过串口通信,当4G与平台连接之后,在保证数据在平台与4G模块之间能正常流转的情况下,可视为单片机使用串口直接与平台进行通信。而原子亦给出了串口通信的相关例程,其中包含串口收发实验,可做参考。

1 问题产生

为了实现需求,先进行两个小实验
3. 模块+上位机实验 : 验证4G模块与平台之间数据收发正常。
4. 电路板串口数据接收实验 :排除电路板硬件异常问题。

1.1 模块+上位机实验

平台发布消息,模块TX引脚输出。通过CH340与串口调试助手相连,接收并显示数据。验证模块能否正常收发数据。
在这里插入图片描述
---------------------补一张串口接收数据图--------------

可以正常收发数据,排除模块问题。
ASCII编码对照表_911查询

1.2 电路板串口数据接收实验

实验硬件:UART1(COM3) , UART3(COM1)实验。
实验现象:UART1 接收到的消息通过UART1打印到串口;UART3 接收到的消息亦通过UART1打印到串口。(UART1做串口调试使用)
实验结论: 排除电路板硬件异常原因,UART1 & UART3 可以正常收发数据。
示例代码:

while(1)
{
		
   if(USART_RX_STA&0x8000)
	{		
		LED0 = 0;			 //点亮LED显示接收到消息	
		len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
		printf("\r\nUART1发送的消息为:\r\n");
		HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);	//发送接收到的数据
		while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);		//等待发送结束
		printf("\r\n\r\n");//插入换行
		USART_RX_STA=0;
	}
	else if(USART3_RX_STA&0x8000)
	{
		LED0 = 1;			 //熄灭LED显示接收到消息	
		len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度
		printf("\r\nUART3发送的消息为:\r\n");
		HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART3_RX_BUF,len,1000);	//发送接收到的数据
		while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);		//等待发送结束
		printf("\r\n\r\n");//插入换行
		USART3_RX_STA=0;
	} 
}	

在这里插入图片描述

1.3 问题来了!

当以上两个小测试完成时,可以确定整个系统软件与硬件无误。也就是说,当电路板上插上4G模块时,即可实现单片机与平台通信的功能!
然而,当平台发布数据时,单片机未能接收到数据。通过软件调试等操作发现,UART3并未进入到接收到数据中断。用示波器测量模块TX引脚,平台发布消息时确实有信号输出!迷惑行为,,,,,,

2 开始分析

2.1 串口数据格式

如下图,可以看出

  1. 无数据时,电平始终为‘1’
  2. 起始位为1位‘0’,停止位为1位‘1’
    在这里插入图片描述
    串口助手配置为:
    bound :115200 ;停止位 :1 ;数据位 :8 ; 检验位 : None
    在这里插入图片描述

2.2 测一波波形

以上两个小测试确实可以验证软件与硬件无误。那么为什么单片机可以接收上位机传来的数据,而不能接收4G模块转发来的数据呢?二者数据有何区别?
验证方法 : 上位机和平台同时发送信息,测其输出信号。测试数据 11(0011_0001 0011_0001)

  • 注 :串口助手及平台发布的数据为字符(ASCII),助手可选择hex发送及显示。
    1. 平台发布数据 11(0011_0001 0011_0001) ,4G转发数据波形如图
    在这里插入图片描述
    **波形分析:**非常漂亮的波形,可以读出数据为 0011_0001 0011_0001(起始位为1位‘0’,停止位为1位‘1’)
    2. 串口助手通过CH340发送数据 11(0011_0001 0011_0001)
    在这里插入图片描述
    CH340 的 TX 引脚输出波形如下:X10_1000_1100_10_1000_1100_10_1011_0000_10_0101_0000_1X
    在这里插入图片描述
    参考串口数据格式,可知:串口发送的数据为:0011_0001 , 0011_0001 , 0000_1101 , 0000_1010

**波形分析:**前两个数据值为32,对应的字符为 ‘1’,‘1’,与发送数据一致。多了后两个值13 10,查询ASCII码为 0D 0A。对应换行键和归位键,嗯?
在这里插入图片描述
查看串口助手,果然!默认勾选了“发送新行”
在这里插入图片描述
再次测试,勾选了“发送新行”数据可以被接收;不勾选了“发送新行”,数据不被接收!可以看出“发送新行”即为单片机识别数据的“校验”格式。那么程序中一定有与“校验”相关的代码,那就找到他!

  • 测波形时遇到一个现象,在这记录一下。

当直接接CH340输出时,图形在上。可以看到高电平只有1,5V左右,电压驱动并不强;当CH340与单片机相连时,发送波形测得的波形如下。当时怀疑过是高电平的问题,在单片机上接了个上拉电阻,波形是好看了,但依旧没有解决问题。因为串口低电平有效,并不要求严格的高电平。
在这里插入图片描述

3 代码分析

关于串口接收的代码如下,一眼就可看到关于0x0a,0x0d的判断,确认是结尾校验无误了。若要修改为 ‘**’ 校验,改为0x2a,0x2a即可。修改后测试成功,没图。

if(huart->Instance==USART3)//如果是串口1
{
	if((USART3_RX_STA&0x8000)==0)//接收未完成
	{
		if(USART3_RX_STA&0x4000)//接收到了0x0d
		{
			if(aRx3Buffer[0]!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
			else USART3_RX_STA|=0x8000;	//接收完成了 
		}
		else //还没收到0X0D
		{	
			if(aRx3Buffer[0]==0x0d)USART3_RX_STA|=0x4000;
			else
			{
				USART3_RX_BUF[USART3_RX_STA&0X3FFF]=aRx3Buffer[0] ;
				USART3_RX_STA++;
				if(USART3_RX_STA>(USART_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收	  
			}		 
		}
	}
}
  • 注 :关于0x0a,0x0d 网上也有不少资料参考。原子的串口助手也有提示正确格式。由于很少使用16进制发送,一致没有注意到!
    在这里插入图片描述

4 新的问题:串口数据累加

新的问题收测试时出现寄存器数据累加情况,具体表现为:

  1. 当串口UART3接收到的数据未加结束校验“**”,单片机未能判断数据接收完毕。
  2. 当下次数据来临(带校验),单片机判断数据发送完毕。通过串口1将数据输出。
    在这里插入图片描述
    再使用例程时,取消"发送新行",会出现同样的问题,由此可以判断是底层代码问题。
    在这里插入图片描述
    猜测:串口在接收未加校验的数据时,已经将数据存入串口接收缓冲buff中。当之后数据(带校验)来临时,继续将数据存入buff,并判断数据接收完毕。此时,多次发送的数据集中在同一buff中,数据为及时清空,由此导致数据累加的情况。
    再来分析这段代码:
    其中,USART3_RX_STA 是串口接收状态标记。定义为:?u16 USART_RX_STA=0; 功能如下
    | bit15 | bit14 | bit13~0 |
    | ---------------- | -------------- | -------------------- |
    | 接收完成标志0x0a | 接收到0X0d标志 | 接收到的有效数据个数 |
if(huart->Instance==USART3)	//如果是串口3
{		
	if((USART3_RX_STA&0x8000)==0)		//接收未完成  USART3_RX_STA最高位判断
	{
		if(USART3_RX_STA&0x4000)		//接收到了第一个0x2a  USART3_RX_STA次高位判断
		{
			if(aRx3Buffer[0]!=0x0a)
			{
				USART3_RX_STA=0;		//接收错误,重新开始
			}
			else USART3_RX_STA|=0x8000;	//接收完成了 
		}
		else 							//还没接收到第一个0x2a
		{	
			if(aRx3Buffer[0]==0x0d)
			{
				USART3_RX_STA|=0x4000;
			}
			else
			{
				USART3_RX_BUF[USART3_RX_STA&0X3FFF]=aRx3Buffer[0] ;  //0X3FFF  USART3_RX_STA 低14位是数据
				USART3_RX_STA++;
				if(USART3_RX_STA>(USART_REC_LEN-1))
				{
					USART3_RX_STA=0;//接收数据错误,重新开始接收
				}	  
			}		 
		}
	}
}

大致画了下流程图,时间关系。不再文字分析了,几个判断嵌套。串口通信实验讲解里关于USART_RX_STA的问题与思考这篇博客文字分析比较详细,推荐一波。
在这里插入图片描述
可以看出,与猜测一致。串口接收缓冲buff并没有进行数据清除。当数据(带校验)未临时,之前的数据会一直寄存在buff中,直到最终发送完毕。(当然数据累加有一定上限,USART_REC_LEN)

若要消除数据累加的情况,就必须在接收完一次不带校验的数据后,及时清除缓冲buff。实际使用中,两次接收数据之间有一定间隔,若能在间隔之中清除buff,即可规避。故加入以下代码,测试一下。

	/* 间隔一定时间清空串口缓冲BUF USART3_RX_BUF */
		if (time_10_ms)		 //定时器 10ms
		{ 
			time_10_ms = 0 ;
			memset(USART3_RX_BUF, 0, sizeof USART3_RX_BUF);  
		}

在这里插入图片描述
测试结果:不加校验的数据串口不识别,定时清空处理,无数据累加情况。测试ok!

总结

没啥写的,强迫症凑一凑。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 18:59:12  更:2021-09-11 18:59:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 0:49:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码