USART串口数据包

USART串口数据包

在这里插入图片描述
先来看两张图,本次程序是串口收发HEX数据包,第二种是串口收发文本数据包,之后两个图,展示的就是接收数据包的思路。

在PB1这里接了一个按键,用于控制。在串口助手,在发送模式和接收模式都选择HEX模式。
在OLED显示这样的数据包,在串口助手这,也显示接收到了这个数据包。

在这里插入图片描述
这个数据包有个规定的格式,就是以FF为包头,FE为包尾,中间固定4个字节为数据,这是STM32发送数据包。
STM32发送数据包:可以在串口助手的发送区,发送一个数据包给STM32,也是同样的格式,以FF开头,中间4个数据为用户数据,最后以FE结尾。

在这里插入图片描述

第二个程序串口收发文本数据包:在串口助手这的发送模式和接收模式都选择文本模式,这个程序我们要发送一个文本数据包,数据包的格式也是个人规定的,此次规定的是,以@符号为包头,中间是数据,如,@LED_ON ,数据也是规定好的指令,最后以换行符为包尾。

可以看到OLED显示接收到了LED_ON,led点亮,然后STM32回传一个字符串LED_ON_OK。如随便给个指令,STM32也能收到,但是返回ERROR_COMMAND,错误指令。

HEX数据包

在这里插入图片描述
在这里插入图片描述

先看—下HEX数据包格式。首先数据包是一种将单独的数据打包起来,整体进行传输的方式,方便进行多字节的通信。在实际应用中,可能需要把多个字节打包成一个整体进行发送。

比如说,我们有个陀摆仪传感器,需要用串口发送数据到STM32,陀螺仪的数据,比如X
轴一个字节、Y轴一个字节、Z轴一个字节,总共3个数据,需要连续不断地发送,但当你像这样XYZ XYZ XYZ这样连续发送的时候,就会出现一个问题,就是接收方,三不知道这数据哪个对应X哪个对应Y、哪个对应Z。因为接收方可能会从任意位置开始接收,所以会出现数据错位的现象。

解决这个现象:就是把这个数据进行分割,把XYZ 分成一个个数据包,这样接收的时候就知道了,数据包的第一个数据是X,数据包的第二个数据是Y,数据包的第三个数据是Z,这就是数据包的任务,就是把同一批的数据进行打包和分割,方便接收方进行识别,

比如,在XYZXYZ数据流中,我们可以在数据包第一个数据,也就是x的数据包上将最高位置1作为标志位,其余数据包最高位置0,当接收到的数据后,判断一下最高位,如果是1,那就是x数据,然后紧跟着的两个数据就分別是Y和Z,这是一种分割方法。**总结:这种方法是把每个数据的最高位当做标志位来进行分割的。**实际例子:如UTF8的编码方法。

本节,讲数据包分割方法,并不是在数据的高位添加标志位这种方式,这种方式破坏了原有的数据,使用起来比较复杂。

我们串口数据包,通常使用的是额外添加包头包尾的这种方式。数据包有2种格式:固定包长,就是每个数据包长度都固定不变,每个数据包前面是包头,后面是包尾。第2种是,可变包长,就是每个数据包长度可以是不一样,我们可以根据用户需求自行规定数据包格式。

例如,我们可以规定一批数据有4个字节,在4个字节之前添加包头0xFF,在之后添加包尾OXFE。当我们接收到OxFF时,就知道一个数据包来了,接萶接收到的4个字节就作为数据包的第1. 2.3.4个数据存储在数组中,最后接收到包尾OxFE时,就可以置一个标志位,告诉程序收到了一个数据包。这样就可以在一个连续不断的数据流中分割出我们想要的数据包了。这就是通过添加包头包尾实现数据分割打包的思路,

接着研究几个问题

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

第一种,限制载荷数据的范围。如果可以的话,我们可以在发送的时候,对数据进行限幅。比如XYZ,3个数据,变化范围都可以是0~100 那就好办了,我们可以在载荷中只发送0-100的数据,这样就不会和包头包尾重复了。

第二种,如果无法避免载荷数据和包头包尾重复,那我们就尽量使用固定长度的数据包。这样由于载荷数据是固定的,只要我们通过包头包尾对齐了数据,我们就可以严格知道,哪个数据应该是包头包尾,哪个数据应该是载荷数据。
在接收载荷数据的时候,我们并不会判断它是否是包头包尾,而在接收包头包尾的时候,我们会判断它是不是确实是包头包尾,用于数据对齐。这样,在经过几个数据包的对齐之后,剩下的数据包应该就不会出现问题了。

第三种,增加包头包尾的数量,并且尽量让它呈现出载荷数据出现不了的状态。比如我们使用FF、FE作为包头,FD、FC作为包尾,这样也可以避免载荷数据和包头包尾重复的情况发生。

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

第三个问题固定包长和可变包长的选择问题
对应HEX数据包来说,如果你的载荷会出现和包头包尾重复的情况,那就最好选择固定包长,这样可以避免接收错误。如果你又会重复,又选择可变包长那数据很容易就乱套了。
如果载荷不会和包头包尾重复,那可以选择可变包长,数据长度,像这样,4位、3位、等等,1位、10位,来回任意变,肯定都没问题。因为包头包尾是唯一的,只要出现包头,就开始数据包,只要出现包尾,就结束数据包,这样就非常灵活了,这就是固定包长和可变包长选择的问题。

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

文本数据包

在这里插入图片描述
这里我同样介绍了固定包长可变包长这两种模式。由于数据被译码成字符形式,因此存在大量字符可以作为包头和包尾,这可以有效避免载荷和包头包尾重复的问题。
例如,以@字符作为包头,以’\r’ '\n’换行符作为包尾,在载荷数据中间允许出现除了包头包尾外的任意字符。这样,文本数据包不用担心载荷和包头包尾重复的问题,使用非常灵活。无论是可变包长还是各种字母、符号、数字,都可以随意使用。

当我们接收到载荷数据时,得到的是一个字符串。在软件中对字符串进行操作和判断,可以实现各种指令控制的功能。此外,字符串数据包的表达意义明显,可以把字符串数据包直接打印到串口助手上,很明显能看出指令和数据。所以这个文本数据包,通常以换行作为包尾,文本数据包通常以
便在打印时逐行显示。

对比HEX数据包和文本数据包,各有优缺点。HEX数据包的优势在于,传输最直接,解析数据简单,适合一些模块发送原始数据,比如使用串口通信的陀摆仪,温温度传感器。其缺点灵活性不足,载荷容易和包头包尾重复。

文本数据包的优点在于,数据直观易于理解,比较适台输入指令进行人机交互的场合。
例如,蓝牙模块常用的AT指令、CNC和3D打印机常用的G代码都是文本数据包的格式,然而,其缺点是解析效率低。

例如,发送数字100时,HEX数据包只需一个字节100即可,而文本数据包则需要三个字节的字符’1,“0,0。收到后还需字符转换为,数据才能得到100。所以,需要根据实际场景来选择和设计数据包格式。数据包格式定义。

数据包收发流程

在这里插入图片描述
首先,发送数据包的过程相对简单。在发送HEX数据包时,可以通过定义一个数组,填充数据,然后使用之前我们写过的SendArray函数发送即可。
在发送文本数据包时,可以通过写一个字符串,然后调用SendString函数发送。因此,发送数据包的过程是可控的,我们可以根据需要发送任何类型的数据包。

接收一个数据包,比较复杂了,这里是固定包长HEX数据包的接收方法,和可变包长文本数据包的接收方法,其他的数据包也都可以套用这个形式,等会儿我们写程序就会根据这里面的流程来。

我们先看一下如何来接收这个固定包长的HEX数据包。要接收固定包长的HEX数据包,我们需要设计一个状态机来处理。根据之前的代码,我们知道每当收到一个字节,程序会进入中断。在中断函数里,我们可以获取这个字节,但获取后需要退出中断。因此,每个收到的数据都是独立的过程,而数据包则具有前后关联性,包括包头、数据和包尾。为了处理这三种状态,我们需要设计一个能够记住不同状态的机制,并在不同状态下执行不同的操作,同时进行状态合理转移。这种程序设计思维就是“状态机”

在这里我们就使用状态机的方法来接收—个数据包,要想设计一个好的状态机程序,画一个这样的状态转移因是必要的。

我们看一下,对于下面这样—个固定包长HEX数据包来说,我们可以定义3个状态,第一个状态是等待包头,第二个状态是收数据,第三个状志是等待包尾,每个状态需要用一个变量来标志一下,比如我这里用变量S来标志,三个状态依次为S=0 S=1 S=2,这一点类似于置标志位,只不过标志位只有0和1,而状态机是多标志位状态的一种方式。

执行流程是:

对于固定包长的HEX数据包,我们可以定义三个状态:等待包头.接收数据,等待包尾。每个状态都可以用一个变量来标志,例如变量S来表示。这三个状态可以依次定义为S=0、 S=1. S=2。类似于置标志位,但标志位只有0和1,而状态机允许多标志位状态。

初始时,S=0表示等待包头状态。当中断发生时,根据S=0的状态,程序会进入等待包头的逻辑。判断数据是不是包头FF,如果收到的数据是FF(包头),则将状态设置为S=1并退出中断。下次再进中断,然后根据S=1的状态,进行接收数据的程序。如果收到的不是FF,就证明数据包没有对齐,那么需要继续等待包头出现,状态保持为S=0。下次中断,还是判断包头的逻辑,直到出现FF,才能转到下一个状态。

当收到FF(包头)后,状态会转移到S=1(接收数据状态)。在此状态下,接收到的数据会被存储在数组中,并记录己收到的数据数量。如果没接收到4个数据,就一直是接收状态,当收到4个数据后,将状态设置为S=2(等待包尾状态)。

在等待包尾状态下(S=2),判断数据是不是FE, 程序会等待收到FE(包尾)。如果收到FE,则将状态重置为S=0(等待包头状态),开始下一个数据包的接收,开启轮回 。如果收到的不是FE,那么需要进入重复等待包尾的状态,直到接收到真正的包尾。

这就是使用状态机接收数据包的思路。这个状态机其实是一种很广泛的编程思路,在很多地方都可以用到,使用的基本步骤是,先根据项目要求定义状态,画几个圈,然后考虑好各个状态在什么情况下会进行转移,如何转移,画好线和转移条件,最后根据这个图来进行编程,这样思维就会非常清晰了。

文本数据包

在这里插入图片描述

同样也是利用状态机,定义3个状态。第一个状态,等待包头,判断收到的是不是我们规定的⑨符号,如果收到@,就进入接收状态,在这个状态(S=1)下,依次接收数据,同时,这个状态还应该要兼具等待包尾的功能。因为这是可变包长,我们接收数据的时候,也要时刻监视.是不是收到包尾了,一但收到包尾了,就结束。

那这里(S=2),这个状态的逻辑就应该是,收到一个数据,判断是不是\r,如果不是,则正常接收,如果是,则不接收,同时跳到下一个状态,等待包尾\n,因为我这里数据包有两个包尾\r\n,所以需要第三个状态,如果只有一个包尾,那在出现包尾之后,就可以直接回到初始状态了,只需要两个状态就行,因为接收数据和等待包尾需要在一个状态里同时进行,由于串口的包头包尾不会出现在数据中,所以基本不会出现数据错位的现象,这就是使用状态机接收文本数据包的方法

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【错题集-编程题】小红的子串(前置和 + 双指针)

牛客对应题目链接:小红的子串 (nowcoder.com) 一、分析题目 利用前缀和的思想,求种类个数在 [l, r] 区间内子串的个数,等于求 [1, r] 区间内个数 - [1, l - 1] 区间内个数。 求种类个数在 [1, count] 区间内子串的个数,可以用滑动…

(深度学习记录)第TR3周:Transformer 算法详解

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 文本的输入处理中,transformer会将输入文本序列的每个词转化为一个词向量,我们通常会选择一个合适的长度作为输入…

Linux系统监控

文章目录 一、系统监控基本介绍二、内存监控2.1、内存监控字段解析2.2、windows下查看内存2.2.1、通过cmd中命令查看内存条信息:2.2.2、通过cmd中命令查看物理内存信息:2.2.3、使用任务管理器查看内存2.2.4、使用资源监视器查看内存2.2.5、使用系统信息工…

Stable Diffusion Webui--安装与使用

最近进行的课程汇报,学习了2023年的CVPR文章《DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation》,因此尝试使用了几种方法对这篇文章的工作进行了一定的复现。本文主要介绍Stable Diffusion Web UI(webui)的安装…

锅炉智能制造工厂工业物联数字孪生平台,推进制造业数字化转型

在制造业快速发展的今天,数字化转型已经成为企业提升竞争力的关键途径。锅炉智能制造工厂工业物联数字孪生平台,作为一种创新的技术解决方案,正以其独特的优势,为制造业的数字化转型提供强大动力。锅炉智能制造工厂工业物联数字孪…

Git基本配置,使用Gitee(一)

1、设置Giter的user name和email 设置提交用户的信息 git config --global user.name "username" git config --global user.email "Your e-mail"查看配置 git config --list2、生成 SSH 公钥 通过命令 ssh-keygen 生成 SSH Key -t key 类型 -C 注释 ssh-…

Stable Diffusion生成图片的参数查看与抹除方法

前几天分享了几张Stable Diffusion生成的艺术二维码,有同学反映不知道怎么查看图片的参数信息,还有的同学问怎么保护自己的图片生成参数不会泄露,这篇文章就来专门分享如何查看和抹除图片的参数。 查看图片的生成参数 1、打开Stable Diffus…

Vxe UI vxe-upload 上传组件,显示进度条的方法

vxe-upload 上传组件 查看官网 https://vxeui.com 显示进度条很简单,需要后台支持进度就可以了,后台实现逻辑具体可以百度,这里只介绍前端逻辑。 上传附件 相关参数说明,具体可以看文档: multiple 是否允许多选 li…

解锁 JavaScript ES6:函数与对象的高级扩展功能

个人主页:学习前端的小z 个人专栏:JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! ES5、ES6介绍 文章目录 💯ES6函数扩展🍓1 默认参数&#x1f35…

【每日刷题】Day53

【每日刷题】Day53 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 1019. 链表中的下一个更大节点 - 力扣(LeetCode) 2. 116. 填充每个节点的下一…

[有监督学习]2.详细图解正则化

正则化 正则化是防止过拟合的一种方法,与线性回归等算法配合使用。通过向损失函数增加惩罚项的方式对模型施加制约,有望提高模型的泛化能力。 概述 正则化是防止过拟合的方法,用于机器学习模型的训练阶段。过拟合是模型在验证数据上产生的误…

DL/ML/RL/TL/FL机器学习框架总结

前言 本文总结了DL/深度学习、ML/机器学习、DML/分布式机器学习、AutoML/自动化机器学习、RL/强化学习、MLaaS/机器学习及服务、SR/语音识别领域的机器学习框架,可作为学习、研究、研发的参考资料。 1.DL/深度学习框架 PyTorch PyTorch是一个开源的Python机器学…

面试题:计算机网络中的七四五是什么?

面试题:计算机网络中的七四五是什么? 计算机网络中说的七四五是指:OSI 七层模型、TCP/IP 四层模型、OSI 与 TCP/IP 的综合五层模型 OSI 七层模型 OSI 将计算机网络分为了七层,每一层抽象底层的内容,并遵守一定的规则…

逆天工具一键修复图片,视频去码。本地部署超详细!!

上一篇文章:逆天工具一键修复图片,视频去码。简直不要太好用!-CSDN博客 根据上一篇文章展示的效果,本文章主要讲如何部署本地github开源项目。博主走了无数弯路,最后精化下来的步骤,超级详细!&a…

godot4.2 + GDextension c++在 vs code 中断点调试配置

游戏开发中如果做不到自己编写的代码做断点调试,无不是瞎子摸象,特别是C这么底层的语言。这2天开始在VS studio中折腾,一直折腾不出结果,几次想要放弃GODOT。最终今天在VS code中搞定了这断点调试C代码。 在上一篇文章我已经做好了…

LabVIEW调用外部DLL(动态链接库)

LabVIEW调用外部DLL(动态链接库) LabVIEW调用外部DLL(动态链接库)可以扩展其功能,使用外部库实现复杂计算、硬件控制等任务。通过调用节点(Call Library Function Node)配置DLL路径、函数名称和…

【机器学习】集成语音与大型语音模型等安全边界探索

探索集成语音与大型语言模型(SLMs)的安全边界 一、引言二、SLMs的潜在安全风险三、对抗性攻击与越狱实验四、提高SLMs安全性的对策五、总结与展望 一、引言 近年来,随着人工智能技术的飞速发展,集成语音与大型语言模型&#xff08…

Java筑基—String类

这里写目录标题 一、字符串的拼接二、获取字符串长度三、字符串转换四、去除前后空白字符五、比较字符串是否相等六、比较字符串是否包含七、字符串是否以某些开始、结尾八、字符串的替换九、字符串的转换十、空串和NULL串 一、字符串的拼接 Java语言允许使用 号拼接两个字符…

WordPress Country State City Dropdown CF7插件 SQL注入漏洞复现(CVE-2024-3495)

0x01 产品简介 Country State City Dropdown CF7插件是一个功能强大、易于使用的WordPress插件,它为用户在联系表单中提供国家、州/省和城市的三级下拉菜单功能,帮助用户更准确地填写地区信息。同时,插件的团队和支持也非常出色,为用户提供高质量的服务。 0x02 漏洞概述 …