C# 串口通信 查找帧头算法,if版

串口通信通常会需要判断帧头.


byte[] headbyte = new byte[]{
    
    0x5F,0x5F,0xF5,0xF5};
/// <summary>
/// 查找帧头, if版
/// </summary>
/// <param name="serialPort"></param>
/// <returns></returns>
public void ReadToPackHead(SerialPort serialPort)
{
    
    
    while (true)
    {
    
    
        if (serialPort.ReadByte() == headbyte[0])
        {
    
    
            if (serialPort.ReadByte() == headbyte[1])
            {
    
    
                if (serialPort.ReadByte() == headbyte[2])
                {
    
    
                    if (serialPort.ReadByte() == headbyte[3])
                    {
    
    
                        break;
                    }
                }
            }
        }
    }
}

不得不说, 这个版本看上去有点傻, 但是从容易理解的角度来讲, 比起while 循环要好的太多了. 一般我们在设计帧头方面, 一般不会太过长的.

如果你更加喜好 循环版, 那么代码如下.

 // 查找帧头 , 循环版, 这个看起来就不是那么容易理解了
 public int ReadToPackHead(SerialPort serialPort)
 {
    
    
     int h = 1;
     while (h < serialPort.BytesToRead)
     {
    
    
         if (serialPort.ReadByte() == headbyte[0])
         {
    
    
             bool ishead = true;

             while (h < headbyte.Length)
             {
    
    
                 if (serialPort.ReadByte() == headbyte[h])
                 {
    
    
                     h++;
                 }
                 else
                 {
    
    
                     ishead = false;
                     break;
                 }
             }
             if (ishead)
             {
    
    
                 break;
             }
         }
     }
     return h;
 }

串口读取数据的主代码

if(serialPort.IsOpen ==false)
{
    
    
     serialPort.Open(); 
     Thread.Sleep(200);
 }

// 现在发送的命令返回的数据, 下次才能读取到.
 serialPort.Write(cmdGetData, 0, cmdGetData.Length);
 Thread.Sleep(500);
 

//找到起始帧
ReadToPackHead(serialPort);
//然后开始读取数据长度帧
byte[] lenbytes = new byte[2];
serialPort.Read(lenbytes, 0, 2);
int onePackLength = BitConverter.ToUInt16(lenbytes, 0);// 16位的数据, 按照8位发的所以需要*2
//pindex = pindex + 2;

Console.WriteLine("本包数据长度" + onePackLength);
//然后循环读取数据, 直到全部读取完整. 如果是小包的数据, 例如20个以下的, 会比较简单.
//但是如果数据量比较大, 则一次无法完全读取完毕所以应该要写入到buffer中然后进行合并.
byte[] onePackBuffer = new byte[onePackLength];
int newDataIndex = 0;

//这里使用循环的原因是, 串口的速度比较慢, 需要等串口把指定长度的数据都传过来之后再进行后续的处理.
while (newDataIndex < onePackLength)
{
    
    
    if (serialPort.BytesToRead == 0)
    {
    
    
        continue;
    }
    serialPort.Read(onePackBuffer, newDataIndex, onePackLength);
    newDataIndex = newDataIndex + serialPort.BytesToRead;
    Thread.Sleep(1);
}
              

猜你喜欢

转载自blog.csdn.net/phker/article/details/127088612