1.HEX数据包格式

 数据包的作用:

把一个个单独的数据打包起来,方便进行多字节的数据通信。

比如:陀螺仪传感器需要用串口发送数据到STM32,陀螺仪的数据有X轴一个字节,Y轴一个字节,Z轴一个字节,3个数据,需要连续不断地发送。如果使用XYZXYZXYZ连续发送就会出现接收方识别不出X,Y,Z对应的数据,即不知道数据哪个对应X,哪个对应Y。因为接收方可能会从任意位置接收,所以会出现数据错位的现象。所以就出现了使用包头包尾把XYZ这一批数据进行分割。分割成一个个数据包,数据包的第一个数据就是X,第二个就是Y。属于把同一批的数据进行打包分割,方便接收方进行识别。

打包的方法可以自己设计,比如在XYZXYA数据流中,数据包的第一个数据即X的数据包,最高位置1,其余数据置0,接收数据后,判断最高位,如果是1就是X数据,接下来的数据就是Y和Z。

这种方法的原理是把每个数据地最高位当作标志位来进行分割。

串口数据包通常使用的收发数据的方法:

额外添加包头包尾

1)固定包长,含包头包尾,就是每个数据包的长度固定不变,数据包前面是包头,后面是包尾

2)可变包长,含包头包尾,也就是每个数据包的长度可以是不一样的,前面是包头,后面是包尾。

数据包格式可以根据用户需求自己规定,也可以是模块开发者规定。

上图固定有效数据包长为4个字节,在加上包头包尾就是6个字节

定义0XFF为包头,在四个字节之后,定义0XFE为包尾

添加包头包尾打包数据思路:

当接收到0XFF后,就知道一个数据包来了,接下来接收的4个字节数据接当作数据包的第1,2,3,4个数据存在一个数组里。当收到包尾0XFE之后,就可以置一个标志位,告诉程序,我接收到了一个数据包。然后新的数据包过来重复之前的过程。这样就可以在数据流中分割出想要的数据包。

问题1:如果传输的数据本身和包头包尾一样,例如传输的数据是0XFF,0XFE可能会引起误判,解决方法如下:

1)限制载荷数据的范围,在发送的时候对数据进行限幅,比如X,Y,Z3个数据,变化范围可以是0-100,就可以在载荷中只发送0-100的数据,这样就不会和包头包尾重复了。

2)如果无法避免数据和包头包尾重复,就尽量使用固定长度的数据包,这样,由于载荷数据固定

只要通过包头包尾对齐数据,就可以严格知道那个数据是包头包尾,哪个数据是载荷数据,在接收载荷数据的时候不会判断它是否是包头包尾,在接收包头包尾时,会判断它是否属于包头包尾,用于数据对齐,经过几个数据包的对齐之后,剩下的数据包就不会出现问题了。

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

问题2:包头包尾的数据并不是全都需要的,比如可以只要一个包头,把包尾删掉,这样数据包的格式就是一个包头FF+4个数据,当检测到FF,开始接收4个字节,置标志位,一个数据包接收完成。但是这样载荷和包头重复的问题会更严重,比如最严重时,载荷全是FF,这时包头也是FF,这时就不知道哪个是包头,加上FE作为结尾后,数据怎么变化都可以分辨出包头包尾。

问题3:固定包长和可变包长的选择

对于HEX数据包,如果载荷和包头包尾会出现重复的情况,最好选择固定包长,这样可以避免接收错误。载荷不会和包头包尾重复,可以选择可变包长这时数据长度可以任意变化,因为这时包头包尾是唯一的。

问题4:各种数据转化为字节流

由于数据包是一个字节一个字节组成的,如果想发送uint16_t,uint32_t,float,double,结构体数据都是可以的,因为它们内部是由一个字节一个字节组成的。

只需用uint8_t指针指向它,把他们当作一个字节数组发送就行了。

2.文本数据包

文本数据包需要经过编码和译码,最终表现出文本格式,但实际上每个文本字符背后还是一个字节的HEX数据。

文本传输数据的模式也是固定包长和可变包长两种模式,由于数据译码成了字符的形式,就会有很多字符可以作为包头包尾,可以有效避免载荷和包头包尾重复。所以文本数据包基本不需要担心数据包和包头包尾重复的问题。可变包长中各种字母,数字,符号都可以随意使用。

当接收到载荷数据之后得到的就是一个字符串,在软件中对字符串进行操作和判断,就可以进行指令控制的功能。字符串表达的意义比较明显

3.两种数据包的优缺点

1)HEX数据包:

优点:传输直接,解析数据简单,比较适合模块发送的原始数据。

比如使用串口通信的陀螺仪,温湿度传感器。

缺点:灵活性不足,载荷容易和包头包尾重复。

2)文本数据包

优点:数据直观易理解,非常灵活,比较适合一些输入指令进行人机交互的场合。

比如蓝牙模块常用的AT指令,CNC和3D打印机常用的G代码。

缺点:解析效率低,比如发送100,HEX数据包发送一个字节100就行了,文本数据包就需要发送3个字节的字符,‘1’,‘0’,‘0’.收到之后还要把字符转换成数据,才能得到100.

可以根据实际场景选择数据包格式

4.数据包的收发流程

1)数据包的发送流程:

比如HEX数据包:定义一个数组,填充数据,用SendArray()函数就行了

文本数据包:写一个字符串,调用SendString()

2)接收数据包流程

固定包长HEX数据包的接收方法:

根据之前的代码,每收到一个字节程序都会进行一次中断,在中断程序函数拿到字节数据,拿到数据后就退出中断,所以每拿到一个数据,都是一个独立的过程。

但是对于数据包,它具有前后关联性,包头之后是数据,数据之后是包尾,对于这3种状态需要不同的处理逻辑,所以需要设计一个能记住不同状态的机制。在不同状态进行不同的操作,同时进行状态的合理转移。

这种程序设计思维叫做状态机

这里使用状态机的方法接收数据包,要想设计一个好的状态机程序,上面的状态转移图是必要的。

对于固定包长HEX数据来说,可以定义3个状态

第一个状态是等待包头,第二个状态是接收数据,第三个状态是等待包尾。

每个状态需要用一个变量来标志比如上面用变量S进行标志.3个状态依次为S=0,S=1,S=2。

类似标志位。

执行流程:S=0,收到一个数据,进中断,根据S=0进入第一个状态的程序,判断数据是不是包头FF,如果是FF则代表收到包头,之后置S=1,退出中断,结束。下次进中断,根据S=1,就可以进行接收数据的程序。如果不是FF,证明数据包没有对齐,应该等待数据包包头的出现。这时状态等然是0,下次进中断,还是判断包头的逻辑。直到出现FF才能转到下一个状态,出现FF就可以转移到接收数据的状态,接收到了数据就直接把它存在数组中,再用另一个变量记录收到了多少个数据,如果没收够4个数据,就一直是接收状态,收够了,就置S=2.下次进中断时就可以进下一个状态了。下个状态就是等到包尾,判断是不是FE,判断完之后置S=0。

当数据和包头重复,导致包头判断错误,包尾位置可能就不是FE,这时就可以进行重复等待包尾的状态,直到接收到真正的包尾。

使用的基本步骤:

根据项目要求定义状态,(画个圈)考虑好各个状态在什么情况下会进行转移,如何转移(画好线和转移条件)根据图进行编程思维更清晰。

2)可变包长文本数据包接收流程

利用状态机定义3个状态

第一个状态:等待包头,判断接收到数据的是不是规定的‘@’符号

,如果收到@就进入接收状态,在这个状态下接收数据,同时,这个状态还应该兼具等待包尾的功能。因为这时可变包长,我们在接收数据的时候,要时刻监视是不是接收到包尾了。一旦接收到包尾了就结束。

这个状态的接受逻辑是:

收到一个数据,判断是不是\r   如果不是就正常接收,如果是就不接收,同时跳到下一个状态,等待包尾\n因为这里有2个包尾。如果只有一个包尾,在出现包尾之后就可以直接回到初始状态了。

串口的包头包尾不会出现在数据中,所以不会出现数据错位的现象

江科大32——USART发送数据包原理相关推荐

  1. 【Java 网络编程】UDP 服务器 客户端 通信 ( DatagramSocket | DatagramPacket | UDP 发送数据包 | UDP 接收数据包 | 端口号分配使用机制 )

    文章目录 I UDP 信息发送接收原理 II UDP 发送和接收端口相同 III UDP 发送信息代码示例 IV UDP 接收信息代码示例 V UDP 服务器端代码示例 VI UDP 客户端代码示例 ...

  2. winpcap 发送数据包

    把WinPcap 中分析数据包的代码复制到VS中,再把WinPcap中数据分析中的一些关于网卡打印的代码复制到VS中. // mist12306.cpp : 定义控制台应用程序的入口点. // #in ...

  3. linux 监听数据包,linux下网络监听与发送数据包的方法(即libpcap、libnet两种类库的使用方法)...

    linux下可以用libpcap函数库实现监听数据包,使用libnet 函数库发送数据包 安装: 在命令行下apt-get install 就可以了 libpcap的使用: /*author hjj ...

  4. linux下网络监听与发送数据包的方法(即libpcap、libnet两种类库的使用方法)

    linux下可以用libpcap函数库实现监听数据包,使用libnet 函数库发送数据包 安装: 在命令行下apt-get install 就可以了 libpcap的使用: /*author hjjd ...

  5. python中如何导入数据包_如何在python中发送数据包?

    我尝试使用这段代码在 python中使用scapy发送数据包 data= "University of texas at San Antonio" a=IP(dst="1 ...

  6. linux网络接口数据重新封包,Linux网络之设备接口层:发送数据包流程dev_queue_xmit...

    写在前面 本文主要是分析kernel-3.8的源代码,主要集中在Network的netdevice层面,来贯穿interface传输数据包的流程,kernel 博大精深,这也仅仅是一点个人愚见,作为一 ...

  7. Day2多种抓包工具介绍以及使用封包监听工具找到挑战数据包实现发送数据包进行挑战

    工具相关证书安装指南 Charles https://blog.csdn.net/weixin_45459427/article/details/108393878 Fidder https://bl ...

  8. ominipeek 发包_Sniffer pro与OmniPeek Personal发送数据包小差别

    在看完haiwanxue的"简单对比omnipeek与sniffer pro报文发送功能.pdf"一文后,偶在使用Omnipeek Personal的发送数据包功能过程中发现Omn ...

  9. coap php 发送,如何使用coap协议向服务器发送数据包

    如何使用coap协议向服务器发送数据包以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! CoAP的URL 在HTTP的世界 ...

最新文章

  1. 链表问题14——在单链表种删除指定值的节点
  2. html5怎么要文字飘起来,html分享之一个超级炫酷的-404飞起来了
  3. 如何在同一台电脑上同时运行2个tomcat
  4. python while函数_详解python while 函数及while和for的区别
  5. java数组解析_Java - 数组解析
  6. GitLab 自动触发 Jenkins 构建
  7. java解析pom.xml_从pom.xml java获取变量
  8. opencv 学习第三课 画线段 圆 椭圆 矩形 多边形 插入文字 代码注释版 保证你每一行都能读懂
  9. 量化选股模型—多因子模型
  10. mysql api百度云盘_利用百度云盘API上传文件至百度云盘
  11. c#选择文件保存路径
  12. 小柯在学JAVA之第二弹
  13. C语言:计算三角形面积与周长
  14. 复现I3D遇到的问题
  15. 采用to_excel保存文件不覆盖原有的sheet
  16. 会计凭证替代BTE增强
  17. 【已解决】win10远程桌面连接报错:出现身份验证错误,要求的函数不受支持(CredSSP)
  18. MySQL学习记录(11.9更新)
  19. asp.net1036-物流管理信息系统#毕业设计
  20. python自学做题记录之找数字

热门文章

  1. 识别车牌号码demo php,Android车牌识别 Demo 源码 能识别蓝色和黄色车牌的OCR android版本...
  2. RAK7258 end node 配置相关
  3. iOS巅峰之开发过程中的小知识点大全
  4. 京瓷打印机1025默认管理员密码_c8520,京瓷打印一体机C8520管理员账号密码多少,怎么设置......
  5. 数据库SQL实战-查找所有员工的last_name和first_name以及对应的dept_name(mysql)
  6. php顺序结构例题,php顺序结构就象一条直线,按照语句出现的先后顺序依次执行...
  7. 机器学习简单介绍LWS
  8. keil5MDK 及cubeMX安装教程
  9. 关于Android全面屏与虚拟按键适配问题
  10. tensorflow2.0 环境下的tfrecord读写及tf.io.parse_example和tf.io.parse_single_example的区别