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

关于串口接收数据不全的问题相关推荐

  1. 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)

    [STM32笔记]HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒.串口唤醒和回调无法一起使用.接收数据不全的问题) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csd ...

  2. STM32如何从串口接收数据,取出数据中的密码段再保存到flash中。

    STM32如何从串口接收数据,取出数据中的密码段再保存到flash中 STM32如何从串口接收数据,取出数据中的密码段再保存到flash中u8 Usart2_buf[256]; unsigned in ...

  3. 【嵌入式】——串口实验——实现芯片串口收发数据,按键中断串口发送数据,串口接收数据中断来控制LED亮/灭

    实验目的: 实现芯片串口收发数据,按键中断串口发送数据:按下按键,向串口发送数据,并通过虚拟终端显示出来: 串口接收数据中断来控制LED亮/灭:通过串口助手向MCU发送数据,"A" ...

  4. 多串口接收数据并显示-自定义串口通信类-调用委托显示数据-保存数据-实例:10串口接收数据并显示加保存

    当时搜了很久,没咋都到合适的思路,就自己整理一份吧 大致实现的功能: 通过串口接收数据,进行解析,然后显示,或者保存数据: 主要:多个串口接收显示都能用: 大致思路: 1.新建一个类SerialPor ...

  5. 单片机串口接收数据的一些经验与教训

    一些好文章 一种单片机数据解析方法:https://mp.weixin.qq.com/s/GVH8MZrlbVKXanD45wOYOw 单片机串口接收数据需要注意以下几点 1.接收数据要有顺序,接收到 ...

  6. STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑

    文章目录 前言 一.打开设备文件 二.串口初始化 三.多线程 四.程序的移植和执行 五.源码(转载请注明出处) 结语 前言 本篇分享: 这次将会用几篇博客分享STM32MP157实现串口接收数据上云的 ...

  7. 串口通信——串口接收数据,发送数据

    十六进制        HEX /hexadecimal   /ˌheksəˈdesɪml/ 十进制            DEC /decimalism     /'desiməlizəm/ 二进制 ...

  8. STM32串口接收数据

    参考串口接收中断处理函数: //------------------------------------------------------------------ //函数名:void USART1 ...

  9. WIN32API串口接收数据简单测试

    进行简单的API中一部分关于串口通信函数的测试,为以后的上位机编写做准备. 下面是一部分从网上和msdn整理的函数说明: ReadFile: BOOL ReadFile (    HANDLE hFi ...

最新文章

  1. autoware中lgsvl Simulator安装与使用:LGsvl Simulator 2021.2.1版(九)
  2. 卫星图片重建洛杉矶3D模型,效果就像谷歌地球,港中大团队提出CityNeRF
  3. wps临时文件不自动删除_今天才发现,原来C盘这些文件夹可以删除,难怪你的电脑越用越卡...
  4. 给大家带来点福利 整理了一些学习网站,问答网站,和IT咨询网站
  5. c语言中闰年的流程图_c语言程序设计流程图怎么画?具体有什么规范,有知道的吗...
  6. apache中文翻译
  7. 如何阅读《如何阅读一本书》?
  8. 彻底解决[未识别的网络][公共网络]的问题
  9. [紧急通告]关于蓝色理想经典论坛无法访问的声明
  10. sendcloud php 群发,PHP精华内容之SendCloud发送邮件
  11. 【研报】供应链流通视角,透视中国商流之变革
  12. 沃通CA证书支持多所高校招投标文件电子签名
  13. 机器学习技术在日常生活和商业领域的应用有哪些,主要带来了什么商业收益?
  14. 2020年电商行业的前景
  15. AI人工智能简介和其定义
  16. android屏幕录制功能,Android利用ADB进行屏幕录制
  17. python爬淘宝商品销量信息_python爬取淘宝商品销量信息
  18. pass by value 与pass by reference 小结
  19. 表单验证与自定义表单验证
  20. 我为什么推荐你使用kindle

热门文章

  1. java中文件选择对话框
  2. 牛逼!Redis 的字符串是这样实现的…
  3. 救命,Linux正在吃掉我的内存!
  4. 我是如何在面试别人Spring事务时“套路”对方的
  5. 2019年我建议你做好三件事情
  6. java中解析xml解读,java解析xml(JDOM)
  7. java dbcp_Java dbcp连接池基本使用方法详解
  8. 自带的数据集_机器学习练习数据哪里找?两行代码搞定!
  9. python datetime格式转换_分别用Excel和python进行日期格式转换成时间戳格式
  10. python有什么好玩的库_你知道Python很火!那你知道它有哪些好玩的库吗?