USART—串口数据包

news2024/12/24 16:59:42

1.HEX数据包定义

数据包的作用是把一个个单独的数据给打包起来,方便我们进行多字节的数据通信,在实际应用中,我们可能需要把多个字节打包为一个整体进行发送,比如说,我们有个陀螺仪传感器,需要用串口发送数据到STM32,陀螺仪的数据,比如X轴一个字节、Y轴一个字节、Z轴一个字节,总共3个数据,需要连续不断地发送,

当你像这样,XYZXYZX么连续发送的时候,就会出现一个问题,就是接收方,它不知道这数据哪个对应义、哪个对应Y、哪个对应Z,因为接收方可能会从任意位置开始接收,可能会出现数据错位的现象,这时候,我们就需要研究一种方式,把这个数据进行分割,把X这一批教据分割开,分成一个个数据包,这样再接受的时候就知道了,数据包的第一个数据就是义、第二个是、第三个是Z,这就是数据包的任务,就是把属于同一批的数据进行打包和分割,方便接收方进行识别,那有关分割打包的方法,可以自己发挥想象力来设计,只要逻辑行得通就行

串口数据包,通常使用的是额外添加包头包尾这种方式,如上图,那当我接收到0xFF之后,我就知道了,一个数据包来了,接着我再接收到的4个字节,就当做数据包的第1、2、3、4个数据,存在一个数组里,最后跟一个包尾,当我收到0xFE之后,就可以置一个标志位,告诉程序,我收到了一个数据包,然后新的数据包过来,再重复之前的过程,这样就可以在一个连续不断的数据流中,分割出我们想要的数据包了,这就是通过添加包头包尾实现数据分割打包的思路。

接着有几个问题:

第一个问题就是,包头包尾和数据载荷重复的问题,这里定义FF为包头,FE为包尾,如果我传输的数据本身就是F和E怎么办呢,那这个问题确实存在,如果数据和包头包尾重复,可能会引起误判,对应这个问题我们有如下几种解决方法,

  • 第一种,限制载荷数据的范围,如果可以的话,我们可以在发送的时候,对数据进行限幅,比如X亿,3个数据,变化范围都可以是0~100,那就好办了,我们可以在载荷中只发送0~100的数据,这样就不会和包头包尾重复了
  • 第二种,如果无法避免载荷数据和包头包尾重复,那我们就尽量使用固定长度的数据包,这样由于载荷数据是固定的,只要我们通过包头包尾对齐了数据,我们就可以严格知道,哪个数据应该是包头包尾,哪个数据应该是载荷数据,在接收载荷数据的时候,我们并不会判断它是否是包头包尾,而在接收包头包尾的时候,我们会判断它是不是确实是包头包尾,用于数据对齐,这样,在经过几个数据包的对齐之后,剩下的数据包应该就不会出现问题了
  • 第三种,就是增加包头包尾的数量,并且让它尽量呈现出载荷数据出现不了的状态,比如我们使用F、FE作为包头,FD、FC作为包尾,这样也可以避免载荷数据和包头包尾重复的情况发生

第二个问题是,这个包头包尾并不是全部都需要的,比如我们可以只要一个包头,把包尾删掉,这样数据包的格式就是,一个包头所,加4个数据,这样也是可以的,当检测到F,开始接收,收够4个字节后,置标志位,一个数据包接收完成,这样也可以,不过这样的话,载荷和包头重复的问题会更严重一些,比如最严重的情况下,我载荷全是FF,包头也是FF,那你肯定不知道哪个是包头了,而加上了E作为包尾,无论数据怎么变化,都是可以分辨出包头包尾的

第三个问题,就是固定包长和可变包长的选择问题,对应HEX数据包来说,如果你的载荷会出现和包头包尾重复的情况,那就最好选择固定包长,这样可以避免接收错误,如果你又会重复,又选择可变包长,那数据很容易就乱套了,如果载荷不会和包头包尾重复,那数据可以选择可变长度,

最后一个问题,就是各种数据转换为字节流的问题,这里数据包都是一个字节一个字节组成的,如果你想发送16位的整型数据、32位的整型数据,float、double,甚至是结构体,其实都没问题,因为它们内部其实都是由一个字节一个字节组成的,只需要用一个uint8 t的指针指向它,把它们当做一个字节数组发送就行了

2.文本数据包

在HX数据包里面,数据都是以原始的字节数据本身呈现的,而在文本数据包里面,每个字节就经过了一层编码和译码,最终表现出来的,就是文本格式,但实际上,每个文本字符背后,其实都还是一个字节的HX数据

这里同样给出了固定包长和可变包长这两种模式,由于数据译码成了字符形式,这就会存在大量的字符可以作为包头包尾,可以有效避免载荷和包头包尾重复的问题,比如我这里规定的就是,以@这个字符作为包头,以以\r\n,也就是换行,这两个字符作为包尾,在载荷数据中间可以出现除了包头包尾的意字符

我们接收到载荷数据之后,得到的就是一个字符串,在软件中再对字符串进行操作和判断,就可以实现各种指令控制的功能了,而且,字符串数据包表达的意义很明显,可以把字符串数据包直接打印到串口助手上,什么指令、什么数据,一眼就能看明自,所以这个文本数据包,通常会以换行作为包尾,这样在打印的时候,就可以一行一行地显示了,非常方便

那HIX数据包和文本数据包这两种对比下来,各有优缺点,

  • HEX数据包优点是,传输最直接,解标数据非常简单,比较适合一些模块发送原始的数据,比如一些使用串口通信的陀螺仪、温湿度传感器,缺点就是灵活性不足、载荷容易和包头包尾重复
  • 文本数据包优点是,数据直观易理解,非常灵活,比较适合一些输入指令进行人机交互的场合,比如蓝牙模块常用的AT指令,CNC和3D打即机常用的G代码,都是文本数据包的格式,那缺点就是解析效率低

如果发送一个数100,HEX数据包就是一个字节100,完事,文本数据包就得是3个字节的字符,'1','0','0',收到之后还要把字符转换成数据,才能得到100,所以说,我们需要根据实际场景来选择和设计数据包格式

3.数据包收发流程

3.1HEX数据包接收

我们先看一下如何来接收这个固定包长的HX数据包,首先,根据之前的代码,我们知道,每收到一个字节,程序都会进一遍中断,在中断函数里,我们可以拿到这一个字节,但拿到之后,我们就得退出中断了,所以,每拿到一个数据,都是一个独立的过程,而对手数据包来说,很明显它具有前后关联性,包头之后是数据,数据之后是包尾,对于包头、数据和包尾这3种状态,我们都需要有不同的处理逻辑,所以在程序中,我们需要设计一个能记住不同状态的机制,在不同状态执行不同的操作,同时还要进行状态的合理转移,这种程序设计思维,就叫做“状态机”   ,

在这里我们就使用状态机的方法来接收一个数据包,要想设计一个好的状态机程序,画一个这样的状态转移图是必要的,对于上面这样一个固定包长HEX数据包来说,我们可以定义3个状态,第一个状态是等待包头,第二个状态是接收数据,第三个状态是等待包尾,

每个状态需要用一个变量来标志一下,比如我这里用变量S来标志,三个状态依次为S=0、S=1、S=2,这一点类似于置标志位,只不过标志位只有0和1,而状态机是多标志位状态的一种方式

然后执行流程是,最开始,S=0,收到一个数据,进中断,根据S=0,进入第一个状态的程序,判断数据是不是包头FF,如果是FF,则代表收到包头,之后置S=1,退出中断,结束,这样下次再进中断,根据S=1,就可以进行接收数据的程序了,那在第一个状态,如果收到的不是FF,就证明数据包没有对齐,我们应该等待数据包包头的出现,这时状态就仍然是0,下次进中断,就还是判断包头的逻辑,直到出现所,才能转到下一个状态,那之后,出现了FF,我们就可以转移到接收数据的状态了,这时再收到数据,我们就直接把它存在数组中,另外再用一个变量,记录收了多少个数据,如果没收够4个数据,就一直是接收状态,如果收够了,就置S=2,下次中断时,就可以进入下一个状态了,那最后一个状态就是等待包尾了,判断数据是不是FE,正常情况,应该是FE,这样就可以置S=0,回到最初的状态,开始下一个轮回,当然也有可能,这个数据不是FE,比如数据和包头重复,导致包头位置判断错了,那这个包尾位置就有可能不是FE,这时就可以进入重复等待包尾的状态,直到接收到真哐的包尾,这样加入包尾的判断,更能预防因数据和包头重复造成的错误,这就是使用状态机接收数据包的思路

这个状态机其实是一种很广泛的编程思路,使用的基本思路是,先根据项目要求定必状态,画几个圈,然后考虑好各个状态在什么情况下会进行转移,如何转移,画好线和转移条件,最后根据这个图来进行编程

3.2文本数据包接收(可变包长)

同样使用状态机,定义三个状态,第一个状态,等待包头,判断收到的是不是我们规定的@符号,如果收到@,就进入接收状态,在这个状态下,依次接收数据,同时,这个状态还应该要兼具等待包尾的功能,因为这是可变包长,我们接收数据的时候,也要时刻监视,是不是收到包尾了,一但收到包尾了,就结束,那这里,这个状态的逻辑就应该是收到一个数据,判断是不是\r,如果不是,则正常接收,如果是,则不接收,同时跳到下一个状态,等待包尾\n,因为我这里数据包有两个包尾\,\n,所以需要第三个状态,如果只有一个包尾,那在出现包尾之后,就可以直接回到初始状态了,只需要两个状态就行,因为接收数据和等待包尾需要在一个状态里同时进行,由于串口的包头包尾不会出现在数据中,所以基本不会出现数据错位的现象,这就是使用状态机接收文本数据包的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git 你要如何打开这个文件

终端输入git命令都会弹出这个框 解决方案: 参考文章:在vscode终端上运行 npm 会询问 “你要如何打开这个文件“_安装 npm脚手架提示你要如何打开-CSDN博客 get-command git后删除对应文件 请注意不要删错了,正常get-command git后对应的是…

微型导轨加工环境需避免的隐患!

微型导轨是一种小巧精密的线性定位解决方案,其高速度、低噪音的特点使得它在现代制造业中扮演着越来越重要的角色。而微型导轨对于加工环境的要求主要体现在以下几个方面: 1、温度控制:加工环境需要保持在适宜的温度范围内,过高或…

【西电电装实习】5. 无人机模块及作用、上位机的操作

文章目录 前言一、硬件结构电源、电源电压测试电路晶振外围陀螺仪信号放大电路及天线空心杯(电极)驱动电路 软件设置整机装配PID 参数设置公式 参考文献 前言 西电电装实习,无人机原理图、上位机的调节方法 一、硬件结构 电源、电源电压测…

RabbitMQ 基础入门

文章内容是学习过程中的知识总结,如有纰漏,欢迎指正 文章目录 前言 1. 重要概念 1.1 Publisher 1.2 Message 1.3 Exchange 1.4 BindingKey 1.5 Routingkey 1.6 Queue 1.7 Consumer 1.8 Connection 1.9 Channel 1.10 Virtual Host 1.11Broker 2. RabbitMQ…

个人学习笔记7-5:动手学深度学习pytorch版-李沐

#人工智能# #深度学习# #语义分割# #计算机视觉# #神经网络# 计算机视觉 13.10 转置卷积 例如,卷积层和汇聚层,通常会减少下采样输入图像的空间维度(高和宽)。然而如果输入和输出图像的空间维度相同,在以像素级分类…

手机玩机常识____展讯芯片刷机平台ResearchDownload的一些基本常识与问题解决

展讯ResearchDownload工具 展讯芯片的刷机工具--ResearchDownload下载工具"是一款专为用户设计的高效、便捷的下载管理软件,它能够帮助用户快速、稳定地从互联网上获取各种文件。这款工具以其强大的功能和良好的用户体验,在众多展讯芯片下载工具中脱…

计算机网络30——Linux-gdb调试命令makefile

1、开始调试 编译时带-g为调试,带调试信息编译后的可执行文件更大 2、进入调试 使用gdb 可执行文件名——进入调试 失败版: 成功版: 3、l命令 l什么都不加——列出10行代码 l 行号——行号的行在中间,向上向下展示10行 4、st…

ppt文件怎么压缩变小一些?8种压缩PPT文件的方法推荐

ppt文件怎么压缩变小一些?在现代工作环境中,PPT文件常常是我们展示信息和分享想法的主要工具。然而,当这些文件变得庞大时,它们不仅会占用大量的存储空间,还可能导致处理速度变慢,影响整体工作效率。这种情…

GIS在线监测SF6密度微水定量检漏仪传感器专用波纹管免焊接格兰头

SF6密度微水在线监测装置配套M12母头5孔格兰头穿波纹管连接器,该传感器能够监测SF6气体的露点,从而实现对SF6气体在线监测。 原理 SF6露点在线监测传感器是一种可以监测SF6气体露点的传感器它的工作原理是通过吸收SF6气体中的水分子来测量SF6气体的露点。…

Jetpack PDF库:解锁Android应用中的PDF功能

Jetpack PDF库:解锁Android应用中的PDF功能 在 Android 开发中,加载 PDF 文件是一个比较常见的需求,但就是这么一个比较常见的功能,原生并没有提供一个比较好的方案,而隔壁 IOS 中实现却是很方便的。。。 下面是当前…

Stream流的思想和获取Stream流

首先介绍流的概念: 流可以理解为一条流水线,在这条流水线中有许多操作,比如筛选所需要的数据,输出打印等, 经过这条流水线,可以获取到自己所需要的数据: -->所以: Stream流的作…

GEE 按范围导出 Sentinel-2 卫星影像

Sentinel-2 卫星提供了高分辨率的地表覆盖图像,广泛应用于农业监测、城市规划、环境变化分析等诸多领域。在 Google Earth Engine (GEE) 中,我们能够按特定地理范围导出这些影像,以支持更深入的研究和分析。 使用方法 💻 GEE 提供…

汽车租赁系统1.0版本

汽车租赁系统1.0版本比较简陋,以后还会有2.0、3.0……就像《我爱发明》里面的一代机器二代机器,三代机器一样,是一个迭代更新的过程(最近比较忙,可能会很久),这个1.0版本很简陋,也请…

Visual Studio Code 高效开发 C/C++ 插件推荐

Visual Studio Code 高效开发插件 C/C 由 Microsoft 提供的官方插件,支持语法高亮、智能感知、调试等功能,是 C/C 开发的基础插件。 C/C Themes 由 Microsoft 提供的官方主题插件,它旨在增强 C 和 C 代码的编辑体验,通过提供代码…

性能诊断的方法(五):架构和业务诊断

关于性能诊断的方法,我们可以按照“问题现象—直接原因—问题根源”这样一个思路去归纳。我们先从问题的现象去入手,包括时间的分析、资源的分析和异常信息的分析。接下来再去分析产生问题现象的直接原因是什么,这里我们归纳了自上而下的资源…

江协科技STM32学习- P13 TIM定时器中断

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

ESP32开发 -- VSCODE+PlatformIO环境安装

参看官网安装:PlatformIO IDE for VSCode 一、安装PlatformIO IDE 参看:日常生活小技巧 – Visual Studio Code 简单使用 扩展中搜索platformIO IDE 当安装完提示重启之后。 打开一个要创建新工程的文件夹: 点击 Create New Project&…

10大差异!Linux运维VS云计算运维深度解析

在当今这个信息技术飞速发展的时代,云计算与容器化技术已经变得无处不在。 随着这些技术的广泛应用,企业对于如何高效、稳定地运维自己的系统和服务提出了更高的要求。 Linux运维和云计算运维作为两种不同的运维模式,它们各自在技术实现、管…

AI问答-HTTP:理解 Content-Disposition

一、简介 Content-Disposition是HTTP协议中的一个响应头字段,它主要用于指示如何处理响应的内容以及如何呈现给用户。这个字段是MIME协议类型的扩展,用于指导MIME用户代理(如浏览器)如何显示附加的文件。Content-Disposition的主…

vscode 设置

code runner设置运行代码弹出运行窗口 要让VSCode在输cmd窗口,可以按照以下步骤进行设置: 1. 打开VSCode并进入”文件”->”首选项”->”设置”,或者使用快捷键Ctrl ,。 2. 在设置页面的搜索栏中输入”External Terminal”&#xf…