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

  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         }
时间: 2024-08-06 11:34:42

关于串口接收数据不全的问题的相关文章

C# 解决串口接收数据不完整

方法1: 使 用缓存机制完成.首先通过定义一个成员变量List<byte> buffer = new List<byte> (4096);用来存放所有的数据,在接收函数里,通过buffer.AddRange()方法不断地将接收到的数据加入到buffer中,并同时对 buffer中的数据进行检验,如果达到一定的长度并且校验结果正确(校验方法在发送方和接收方一致),再进行处理.具体代码如下:代码 private List<byte> buffer = new List<

C# 串口接收数据中serialPort.close()死锁

最近在做一个有关高铁模拟仓显示系统的客户端程序,在这个程序中要运用串口serialPort传输数据,因为每次接收数据结束后要更新UI界面,所以就用到了的Invoke,将更新UI的程序代码封装到一个方法中,然后通过Incoke调用,程序跑起来没有任何问题,但是当你执行serialPort.close()是程序就会发生死锁,整个程序卡在那里动都动不了.上网查了很多资料,有各种这样的说法,有的说定义一个接收数据的标志,如果在执行关闭程序是进行判断,如果数据接收完了就关闭串口,没有的话继续执行,但是经过

2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题

本文用的是VS2013MFC写串口数据接收: 第一步:首先建立一个MFC工程,成功后会跳出一个对话框,直接在对话框上点击右键->点击插入ACTIVAE控件->选择MicrosoftCommunications Control, version 6.0 成功后会显示一个电话的图标在对话框上,运行起来不会显示的 不用担心这个美观问题.如果没有这个插件的话,可能是版本太低  可以自己下载一个补上 第二步:大概的窗体搞好:   那个显示图片的大框是PICTURE控件变量 然后就要项目->类向导中

Qt串口通信接收数据不完整的解决方法(传输图片)

在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况.因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分.因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据. 本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快. //发送 [cpp] vie

Qt5自带串口调试 --使用signal接收数据,自动侦测端口列表

Qt5自带串口初步用一下感觉还不错. 调试记录 .pro文件增加 QT += serialport .h文件增加 #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> private slots: void my_readuart();//串口接收数据槽函数 private: QSerialPort *my_serialport; .cpp文件 构造函数内     foreach (c

stm32 串口收发数据不稳定问题

用中断接收串口数据时,有时会存在串口接收数据错乱的问题,此时需要配置的时候为 uint8 u8Data; if ( USART_GetITStatus(USART1,USART_IT_RXNE) == SET ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE);  //实际测试,先清除后存在,效果很好 u8Data=USART_ReceiveData(USART1); if (bUsart1ReFlag == 0) { g_s8RxDebugBuf

delphi SPCOMM 接收数据不完整!该如何解决

SPCOMM 接收数据不完整!该如何解决 SPCOMM 接收数据不完整!我作了一个 读取地磅数据的程序,是用spcomm接收的! 总共有五台地磅,其他4台地磅数据读取都正常.但是有一台接收数据的时候,总是接收不到完整的数据,基本上小于100的数据都读不到,比如:地磅上显示1234,但是接收到的数据是12.  地磅上显示60,接收不到数据. 有时地磅上什么东西都没有,但是显示接收到 5 . 这个地磅用原来硬件供应商提供的程序可以正常工作.用我写的程序,偶尔也能正常读到数据(用程序测试了半天,有几次

STM32串口接收小结

STM32串口接收数据 稍微理一下思路,一个数据从电脑发送到STM32,然后在从STM32返回到电脑显示出来. 如上图所示,发送(1所示的路线)前,STM32的淳口需要初始化的设置.包括:波特率,字长,硬件流,停止位,奇偶校验位,模式(接收,发送,接收和发送),串口的基地址(Instance).在初始化串口的函数里面,需要调用到HAL_UART_MspInit(),这是一个虚函数(_weak),HAL_UART_MspInit()会调用到HAL_GPIO_Init(),把IO口进行配置.(模式,

通过串口接收带有标识符的数据方法

在做串口通信过程中,下位机向上位机发送的串口数据有时候需要带有指定的标识符,便于上位机根据标识符判断后续几位数据是做什么用的.也就是下位机和上位机约定数据帧的传输格式,便于在上位机将数据分离,当然这种数据帧格式可以自定义. 今天用arduino作为下位机,模拟数据通过自定义格式发送数据帧,利用串口将数据帧发送到android上位机,上位机用java代码实现数据提取,并在界面实时显示接收数据,虽然是模拟数据通过串口发送,但在实际项目开发中,原理相通. 以下是arduino代码,通过设定定时器,当接