在每次讀串口資料時,時常讀到的不是一包完整的資料,一包完整的資料中的前半段可能是在上次讀到的,後半段資料可能在這次讀到。因此,需要將每次讀到的資料都儲存,再從中分離出每包完整的資料。
namespace test
{
public partial class Form1 : Form
{
//串口通訊資料包格式:起始標識符(Hex) + 資料(ANSIC string) + 校正碼(ANSIC string) + 結束標識符(Hex)
private readonly byte startFlag = 0x02;//資料包起始標識符
private readonly byte endFlag = 0x03;//資料包結束標識符
private List<byte> receivedBytesList = new List<byte>();//接收的資料儲存於此
public Form1()
{
InitializeComponent();
}
//通過事件觸發來接收串口資料
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (serialPort1.BytesToRead > 0)
{
//全部讀取串口資料儲存之
byte[] bts = new byte[serialPort1.BytesToRead];
serialPort1.Read(bts, 0, bts.Length);
receivedBytesList.AddRange(bts);
//根據起始標識符和結束標識符,在 receivedBytesList 中分離出資料包,並解析
while (true)
{
int startIndex = receivedBytesList.FindIndex(delegate(byte t) { return t == startFlag; });
if (startIndex > -1)
{
int endIndex = receivedBytesList.FindIndex(startIndex, delegate(byte t) { return t == endFlag; });
if (endIndex > startIndex)
{
//得到我要的一包完整資料,包括起始標識符和結束標識符
byte[] myBytes = receivedBytesList.GetRange(startIndex, endIndex - startIndex + 1).ToArray();
//其他動作,如解析資料等
//Parse(myBytes);
//去除已經被解析的資料區段,
receivedBytesList.RemoveRange(0, endIndex + 1);
}
else
{
break;
}
}
else
{
break;
}
}
}
}
}
}