c#串口通信(三)--半双工通信的数据接收

上文提到了如何简单发送和接收串口数据。
在实际操作中,对于半双工通信(一问一答),如果需要一次发送多个指令,用DataReceived事件判断是否接收完毕,再发送下一条数据,不是很好的选择。
个人采用如下的方式,总的来说就是发送指令之后,用循环判断是否完成接收,未完成就延时一段时间再去判断,直到接收完成后再执行下一条指令:
先写好单条一问一答的函数:
在这里插入图片描述
有关接收事件GetCallbackData()代码如下:

private byte[] DataBuffer = new byte[1000];
private int bufferReadLength = 0;
private bool isAccept = false;
public object GetCallbackData()
{
   if (!serialPort.IsOpen) return null;
   bool isEnd = false;
   while (!isEnd)//如果数据未接收完,则等待一会继续接收,直到接收完成跳出循环
   {
       Thread.Sleep(400);//延时等待接收完数据 
       isEnd = ComReceiveData();
   }
   var data = Analyse(DataBuffer.Clone() as byte[]);//将接收的byte[]数据按要求解析出来
   DataBuffer = new byte[1000];
   isAccept = false;
   return data;
}
/// <summary>
/// 判断接收到的数据是否完整,并将接收的正确数据放入缓存变量中
/// </summary>
/// <param name="data">接受的数据</param>
public bool ComReceiveData()
{
  try
  {
      byte[] buffle = new byte[serialPort.BytesToRead];
      serialPort.Read(buffle, 0, buffle.Length);//查看返回的数据buffle
      if (buffle.Length <= 0)
      {
          //MessageBox.Show("读取失败,请检查是否打开设备");
          return true;
      }
      if (serialPort == null)
      {
          return true;
      }
      if (!serialPort.IsOpen)//串口在关闭时不接收数据 为了防止关闭串口时卡死的问题
      {
          serialPort.DiscardInBuffer();//丢弃接收缓冲区数据
          return true;
      }
      bool isAll = false;
      if (!isAccept)
      {
          isAccept = true;
      }
      if (DataBuffer[0] == 0x77 && DataBuffer[1] == 0xCC)//上次未接收完
      {
          var Length = DataBuffer.Length;
          DataBuffer = RS485Helper.AddBytes(DataBuffer, buffle);//追加新数据
          isAll = (Length == buffle.Length + bufferReadLength);
      }
      else//开始接收
      {
          if (buffle[0] == 0x77 && buffle[1] == 0xCC)
          {
              bufferReadLength = buffle.Length;
              var length = (ushort)(buffle[3] << 8) + (ushort)buffle[4] + 6;//包长加包头包尾才是总长度
              DataBuffer = new byte[length];
              DataBuffer = RS485Helper.AddBytes(DataBuffer, buffle, false);//原缓存数据上追加新数据
              isAll = (length == buffle.Length);
          }
      }
      return isAll;
  }
  catch(Exception ex)
  {
      throw ex;
  }

}

最后,在发送多条命令的地方使用函数
在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页