关于串口接收数据不全的问题
1 /// <summary> 2 /// 字节缓冲器 3 /// </summary> 4 public class ByteQueue 5 { 6 private List<byte> m_buffer = new List<byte>(); 7 public bool Find() 8 { 9 if (m_buffer.Count == 0) 10 return false; 11 int HeadIndex = m_buffer.FindIndex(o => o == 0xAA); 12 13 if (HeadIndex == -1) 14 { 15 m_buffer.Clear(); 16 return false; //没找到AA 17 } 18 19 else if (HeadIndex != 0) //不为开头移掉之前的字节 20 { 21 if (HeadIndex > 1) 22 m_buffer.RemoveRange(0, HeadIndex); 23 } 24 25 int length= GetLength(); 26 27 if (m_buffer.Count <length) 28 { 29 return false; 30 } 31 32 int TailIndex = m_buffer.FindIndex(o => o == 0x55); //查找55的位置 33 34 if (TailIndex == -1) 35 { 36 //这一步为防止连发一个AA开头的包后,没发55,而又发了一个AA 37 int head = m_buffer.FindLastIndex(o => o == 0xAA); 38 if (head > -1) 39 { 40 m_buffer.RemoveRange(0, head); 41 } 42 return false; 43 } 44 else if (TailIndex + 1 != length) //计算包尾是否与包长度相等 45 { 46 m_buffer.RemoveRange(0, TailIndex); 47 return false; 48 } 49 50 return true; 51 } 52 53 /// <summary> 54 /// 命令类型 55 /// </summary> 56 /// <returns></returns> 57 public byte Cmd() 58 { 59 if (m_buffer.Count >= 2) 60 { 61 return m_buffer[1]; 62 } 63 return 0; 64 } 65 66 /// <summary> 67 /// 序号 68 /// </summary> 69 /// <returns></returns> 70 public byte Number() 71 { 72 if (m_buffer.Count >= 3) 73 { 74 return m_buffer[2]; 75 } 76 return 0; 77 } 78 79 /// <summary> 80 /// 包长度 81 /// </summary> 82 /// <returns></returns> 83 public int GetLength() 84 { 85 int len = 5;//AA 命令类型 序号 校验和 55 86 if (m_buffer.Count >= 3) 87 { 88 switch (m_buffer[2]) //第三字节为序号 89 { 90 case 0x00: //序号 91 return len + 16; 92 case 0x01: //序号 93 return len + 10; 94 case 0x02: //序号 95 return len + 12; 96 } 97 } 98 return 0; 99 } 100 /// <summary> 101 /// 提取数据 102 /// </summary> 103 public void Dequeue(byte[] buffer, int offset,int size) 104 { 105 m_buffer.CopyTo(0,buffer,offset,size); 106 m_buffer.RemoveRange(0, size); 107 } 108 109 /// <summary> 110 /// 队列数据 111 /// </summary> 112 /// <param name="buffer"></param> 113 public void Enqueue(byte[] buffer) 114 { 115 m_buffer.AddRange(buffer); 116 } 117 }
1 private ByteQueue queue = new ByteQueue(); 2 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 3 { 4 int len = serialPort1.BytesToRead; 5 if (len > 0) 6 { 7 byte[] temp = new byte[len]; 8 serialPort1.Read(temp, 0, len); 9 queue.Enqueue(temp); 10 while (queue.Find()) //while可处理同时接收到多个AA ... 55 ,AA...55的包 11 { 12 int length = queue.GetLength(); 13 byte[] readBuffer = new byte[len]; 14 queue.Dequeue(readBuffer, 0, length); 15 OnReceiveData(readBuffer); //<这里自己写一个委托吧就OK了 16 } 17 18 } 19 20 }
private List<byte> buffer = new List<byte>(4096);
private void sp_DataReceived(objectsender, EventArgs e) //sp是串口控件
{
int n = sp.BytesToRead;
byte[] buf = new byte[n];
sp.Read(buf, 0, n);//1.缓存数据
buffer.AddRange(buf);
//2.完整性判断
while (buffer.Count >= 4) //至少包含帧头(2字节)、长度(1字节)、校验位(1字节);根据设计不同而不同
{
//2.1 查找数据头
if (buffer[0] == 0x01) //传输数据有帧头,用于判断
{
int len = buffer[2];
if (buffer.Count < len + 4) //数据区尚未接收完整
{
break;
}
//得到完整的数据,复制到ReceiveBytes中进行校验
buffer.CopyTo(0, ReceiveBytes, 0, len + 4);
byte jiaoyan; //开始校验
jiaoyan = this.JY(ReceiveBytes);
if (jiaoyan != ReceiveBytes[len+3]) //校验失败,最后一个字节是校验位
{
buffer.RemoveRange(0, len + 4);
MessageBox.Show("数据包不正确!");
continue;
}
buffer.RemoveRange(0, len + 4);
/执行其他代码,对数据进行处理。
}
else //帧头不正确时,记得清除
{
buffer.RemoveAt(0);
}
}
}
转载于:https://www.cnblogs.com/laowengdiaodayu/p/4553394.html
关于串口接收数据不全的问题相关推荐
- 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)
[STM32笔记]HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒.串口唤醒和回调无法一起使用.接收数据不全的问题) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csd ...
- STM32如何从串口接收数据,取出数据中的密码段再保存到flash中。
STM32如何从串口接收数据,取出数据中的密码段再保存到flash中 STM32如何从串口接收数据,取出数据中的密码段再保存到flash中u8 Usart2_buf[256]; unsigned in ...
- 【嵌入式】——串口实验——实现芯片串口收发数据,按键中断串口发送数据,串口接收数据中断来控制LED亮/灭
实验目的: 实现芯片串口收发数据,按键中断串口发送数据:按下按键,向串口发送数据,并通过虚拟终端显示出来: 串口接收数据中断来控制LED亮/灭:通过串口助手向MCU发送数据,"A" ...
- 多串口接收数据并显示-自定义串口通信类-调用委托显示数据-保存数据-实例:10串口接收数据并显示加保存
当时搜了很久,没咋都到合适的思路,就自己整理一份吧 大致实现的功能: 通过串口接收数据,进行解析,然后显示,或者保存数据: 主要:多个串口接收显示都能用: 大致思路: 1.新建一个类SerialPor ...
- 单片机串口接收数据的一些经验与教训
一些好文章 一种单片机数据解析方法:https://mp.weixin.qq.com/s/GVH8MZrlbVKXanD45wOYOw 单片机串口接收数据需要注意以下几点 1.接收数据要有顺序,接收到 ...
- STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑
文章目录 前言 一.打开设备文件 二.串口初始化 三.多线程 四.程序的移植和执行 五.源码(转载请注明出处) 结语 前言 本篇分享: 这次将会用几篇博客分享STM32MP157实现串口接收数据上云的 ...
- 串口通信——串口接收数据,发送数据
十六进制 HEX /hexadecimal /ˌheksəˈdesɪml/ 十进制 DEC /decimalism /'desiməlizəm/ 二进制 ...
- STM32串口接收数据
参考串口接收中断处理函数: //------------------------------------------------------------------ //函数名:void USART1 ...
- WIN32API串口接收数据简单测试
进行简单的API中一部分关于串口通信函数的测试,为以后的上位机编写做准备. 下面是一部分从网上和msdn整理的函数说明: ReadFile: BOOL ReadFile ( HANDLE hFi ...
最新文章
- autoware中lgsvl Simulator安装与使用:LGsvl Simulator 2021.2.1版(九)
- 卫星图片重建洛杉矶3D模型,效果就像谷歌地球,港中大团队提出CityNeRF
- wps临时文件不自动删除_今天才发现,原来C盘这些文件夹可以删除,难怪你的电脑越用越卡...
- 给大家带来点福利 整理了一些学习网站,问答网站,和IT咨询网站
- c语言中闰年的流程图_c语言程序设计流程图怎么画?具体有什么规范,有知道的吗...
- apache中文翻译
- 如何阅读《如何阅读一本书》?
- 彻底解决[未识别的网络][公共网络]的问题
- [紧急通告]关于蓝色理想经典论坛无法访问的声明
- sendcloud php 群发,PHP精华内容之SendCloud发送邮件
- 【研报】供应链流通视角,透视中国商流之变革
- 沃通CA证书支持多所高校招投标文件电子签名
- 机器学习技术在日常生活和商业领域的应用有哪些,主要带来了什么商业收益?
- 2020年电商行业的前景
- AI人工智能简介和其定义
- android屏幕录制功能,Android利用ADB进行屏幕录制
- python爬淘宝商品销量信息_python爬取淘宝商品销量信息
- pass by value 与pass by reference 小结
- 表单验证与自定义表单验证
- 我为什么推荐你使用kindle
热门文章
- java中文件选择对话框
- 牛逼!Redis 的字符串是这样实现的…
- 救命,Linux正在吃掉我的内存!
- 我是如何在面试别人Spring事务时“套路”对方的
- 2019年我建议你做好三件事情
- java中解析xml解读,java解析xml(JDOM)
- java dbcp_Java dbcp连接池基本使用方法详解
- 自带的数据集_机器学习练习数据哪里找?两行代码搞定!
- python datetime格式转换_分别用Excel和python进行日期格式转换成时间戳格式
- python有什么好玩的库_你知道Python很火!那你知道它有哪些好玩的库吗?