C# 解决串口接收数据不完整
2021-05-12 07:27
标签:remove 校验位 show end else 全局 tin 完整 函数 方法1: 使 用缓存机制完成。首先通过定义一个成员变量List //1.缓存数据 方法2: 接收数据的事件如下: if (instr == "681212680002083203000000000002000100000501FF4716") 解决办法有两种,
方法二:
private void sp_DataReceived(objectsender, EventArgs e) //sp是串口控件
{
int n = sp.BytesToRead;
byte[] buf = new byte[n];
sp.Read(buf, 0, n);
buffer.AddRange(buf);
//2.完整性判断
while (buffer.Count >= 4) //至少包含帧头(2字节)、长度(1字节)、校验位(1字节);根据设计不同而不同
{
//2.1 查找数据头
if (buffer[0] == 0x01) //传输数据有帧头,用于判断
{
int len = buffer[2];
if (buffer.Count {
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);
}
}
}
void commPlc_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buffer=new byte[commPlc.BytesToRead];
commPlc.Read(buffer, 0, commPlc.BytesToRead);
instr = "";
foreach (byte b in buffer)
{
instr += b.ToString("X2");
}
主程序中:
outbuf = new byte[6] { 0x10, 0x02, 0x00, 0x5C, 0x5E, 0x16 };
commPlc.Write(outbuf, 0, outbuf.Length);
System.Threading.Thread.Sleep(600);
{
………………………………
}
一个是在DataReceived事件里加入
System.Threading.Thread.Sleep(600);
byte[] buffer=new byte[commPlc.BytesToRead];
这样可以等待缓冲区的数据缓冲好,一次接收数据,也就是只触发一次DataReceived事件
将instr定义成全局变量,删除事件里的instr="";这样可以保证每次触发的时候不会清空instr