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串口自定义数据接收协议 的相关文章

  • 初始化 ST-Link 设备时出错 - 无法连接到设备

    我目前正在使用 ST Link 调试器对我的 STM32F3 Discovery 板进行编程 我使用的IDE是Atollic TrueStudio 5 5 2 现在我面临一个非常奇怪的问题 那就是我不断收到消息 初始化 ST Link 设备
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • HAL库学习

    CMSIS简介 CMSIS Cortex Microcontroller Software Interface Standard 微控制器软件接口标准 由ARM和其合作的芯片厂商 ST NXP 软件工具厂商 KEIL IAR 共同制定的标准
  • STM32F103概要

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

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • SHT10温湿度传感器——STM32驱动

    实验效果 硬件外观 接线 3 3V供电 IIC通讯 代码获取 查看下方 END
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 擦除后无法写入闪存

    所以我不能在擦除后直接写入内部闪存 如果写操作之前没有擦除操作 那么我可以 有什么想法吗 编程函数返回 成功写入 值 但查看内存时 没有写入任何数据 这是代码 uint32 t pageAddress 0x08008000 uint16 t
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d

随机推荐

  • 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 串口数据累加总结 写在