STM32串口自定义数据接收协议

2023-05-16

文章目录

    • 写在前面
    • 0 需求
    • 1 问题产生
      • 1.1 模块+上位机实验
      • 1.2 电路板串口数据接收实验
      • 1.3 问题来了!
    • 2 开始分析
      • 2.1 串口数据格式
      • 2.2 测一波波形
    • 3 代码分析
    • 4 新的问题:串口数据累加
    • 总结

写在前面

最近使用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!

总结

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32串口自定义数据接收协议 的相关文章

  • 如何更改闪存的起始地址?

    我正在使用 STM32F746ZG 和 FreeRTOS Flash的起始地址是0x08000000 但我想把它改成0x08040000 我通过谷歌搜索了这个问题 但没有找到解决方案 我更改了链接器脚本 如下所示 MEMORY RAM xr
  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • 在没有 IDE 的情况下如何使用 CMSIS?

    我正在使用 STM32F103C8T6 并想使用 CMSIS 这本质上只是寄存器定义 没有代码 让我的生活更轻松 同时仍保持在较低水平 问题是我不知道如何安装该库以便在命令行上使用 Makefile 使用 所有文档似乎都与特定于供应商的 I
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 核心耦合内存在 STM32F4xx 上可执行吗?

    尝试从 STM32F429s CCM 运行代码 但每当我命中 CCM 中的第一条指令时 我总是会遇到硬故障 并且 IBUSERR 标志被设置 该指令有效且一致 STM32F4xx 是否可能不允许从 CCM 执行 数据访问效果良好 alios
  • STM32 Nucleo 上的上升沿中断多次触发

    我正在使用 STM32 NUCLEO F401RE 微控制器板 我有一个扬声器 经过编程 当向上 向下推操纵杆时 可以按设定的量改变频率 我的问题是 有时 通常 当向上 向下推动操纵杆时 频率会增加 减少多次 这意味着 ISR 正在执行多次
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE

随机推荐

  • sealos issue #2157 debug 思路流程记录

    sealos issues 2157 debug思路流程 前言分析issue剖析源码解决方案总结 前言 这个项目蛮有意思的 xff0c sealos 是以 kubernetes 为内核的云操作系统发行版 boss上看到 gt 沟通 gt 解
  • 系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?

    系统设计场景题 MySQL使用InnoDB xff0c 通过二级索引查第K大的数 xff0c 时间复杂度是多少 xff1f 前言明确场景对齐表的结构分析时间复杂度执行一条 select 语句 xff0c 期间发生了什么 xff1f 分析性能
  • 《嵌入式系统》 |(四) STM32软件架构 知识梳理

    系列索引 嵌入式系统 嵌入式系统 重点知识梳理 目录 CMSIS软件架构库文件说明 CMSIS软件架构 CMSIS概述 CMSIS软件架构由四层 xff1a 用户应用层 操作系统及中间件接口层 CMSIS层和硬件层 由三部分构成 核内外设访
  • Cmake链接第三方库的三种方法

    Cmake链接第三方库的三种方法 本文介绍链接第三方库的3种方法 以OpenBLAS举例 使用的工程名称为Test lib xff08 可执行文件名字 xff09 xff0c 主程序为library c 代码中的各路径请自行替代 xff1a
  • SADP功能使用

    SADP主要使用的是链路层多播及UDP多播的原理进行实现的 1 链路层多播 span class token function socket span span class token punctuation span PF PACKET
  • MatlabR2022b + Visual Studio环境配置

    在Matlab中输入 mex setup c 43 43 命令确认MEX使用VS2022编译环境 VC 43 43 目录 包含目录 添加 D Matlab2022b extern include VC 43 43 目录 库目录 添加 D M
  • ROS小车自主导航

    在进行ROS小车自主导航时 xff0c 需要用到三维可视化软件rviz xff0c 然而出现了问题 问题 xff1a 在运行rosrun rviz rviz xff0c 导入自己导航的程序后 xff0c 需要通过2D Pose Estima
  • SIYI AK28 遥控器接收机的SBUS口与STM32通讯

    SBUS介绍 SBUS是Futaba公司定义的一种串口通信协议 xff0c Futaba的产品应用越来越广泛 xff0c 不论是航模 xff0c 无人机 xff0c 还是机器人 xff0c 遥控车 xff0c 总能有它的身影 SBUS是一个
  • 基于STM32F407四旋翼无人机---AK8975磁力计(四)

    基于STM32F407四旋翼无人机 AK8975磁力计 xff08 四 xff09 磁力计基本介绍1 2 磁力计原理图 2 磁力计数据获取3 磁力计椭球拟合校准3 1 简单介绍椭球拟合 磁力计基本介绍 该模块采用高灵敏度霍尔传感器技术 xf
  • 硬链接与软链接

    硬链接 hard link 与软链接 xff08 又称符号链接 xff0c 即 soft link 或 symbolic link xff09 链接为 Linux 系统解决了文件的共享使用 xff0c 还带来了隐藏文件路径 增加权限安全及节
  • 基于STM32F407四旋翼无人机 --- 姿态解算讲解(四元数)(叉积法融合陀螺仪数据和加速度数据)(五)

    基于STM32F407四旋翼无人机 姿态解算讲解 xff08 五 xff09 姿态解算姿态解算定义欧拉角四元数四元数性质 方向余弦矩阵四元数方向余弦矩阵 叉积法融合陀螺仪数据和加速度数据叉积运算 一阶龙格库塔法四元数更新获得欧拉角 姿态解算
  • 基于STM32F407四旋翼无人机---PID算法控制(六)

    基于STM32F407四旋翼无人机 PID算法控制 xff08 六 xff09 PID介绍PID仿真分析 PID介绍 PID介绍 此算法是由P xff08 比例 xff09 I xff08 积分 xff09 和D xff08 微分 xff0
  • 四足机器人(一)----MATLAB simulink对四足机器人物理建模

    四足机器人 xff08 一 xff09 MATLAB simulink对四足机器人物理建模 一 本设计中用的是网上下载的别人已经画好的四足机器狗的3D模型 那么我们就需要将这些3D模型导入到MATLAB的建模中 xff0c 打开MATLAB
  • 四足机器人(二)---运动学逆解和步态规划

    四足机器人 xff08 二 xff09 运动学逆解和步态规划 运动学逆解步态规划MATLAB仿真 运动学逆解 其实运动学分为运动学正解和运动学逆解 xff0c 二者有什么区别呢 xff1f 因为在四足机器人中用的是12个舵机 xff0c 所
  • 四足机器人(三)--- 姿态控制

    四足机器人 xff08 三 xff09 姿态控制 概述姿态表示使用MATLAB实现姿态控制算法效果 概述 四足机器人运动过程中 xff0c 身体部分的姿态会不断地发生变化 假如机器人的足端一直保持与地面接触且相对位置不发生变化 xff0c
  • VSCode+python+opencv搭建过程

    VSCode 43 python 43 opencv搭建过程 python安装VSCode安装安装opencv python安装 首先打开python的官网 www python org xff0c 进入python官网下载页面 xff0c
  • 智能家居之主机---计划筹备

    智能家居之主机 计划筹备 前言绪言前期构思 硬件平台结构平台 前言 绪言 感觉有一年多没发过文章了 xff0c 这一年多太忙了 xff0c 来到新的公司后要学的太多了 xff0c 代码风格 xff0c 架构 xff0c 操作系统 xff0c
  • 智能家居之主机--环境搭建

    智能家居之主机 环境搭建 硬件环境软件环境结构 硬件环境 上节说到硬件平台的搭建 xff0c 之前是在altium designer上面画好的 xff0c 现在要支持国产 xff0c 没办法只能在立创EDA上面重新画了 xff0c 有的人说
  • 智能家居之主机--驱动层搭建

    智能家居之主机 驱动层搭建 bsp 底层驱动bsp gpiobsp adcbsp uartbsp timer 伪调度 bsp 底层驱动 bsp gpio 利用一个config h的配置文件 xff0c 把所有要使用的gpio的属性配置好 x
  • STM32串口自定义数据接收协议

    文章目录 写在前面0 需求1 问题产生1 1 模块 43 上位机实验1 2 电路板串口数据接收实验1 3 问题来了 xff01 2 开始分析2 1 串口数据格式2 2 测一波波形 3 代码分析4 新的问题 xff1a 串口数据累加总结 写在