经过测试发现这两种方法在数据包发送间隔小于200ms时,会出现数据丢包的问题,现在将这两种方法结合起来,同时将方法二改进为双缓存机制,经过测试发现可以解决数据的丢包的问题。
public MainForm()
{
InitializeComponent();
serialPort_port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);//串口接收事件
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//关闭夸线程检查
}
二、MainForm类下定义接收事件的委托并编写接收程序
public delegate void PortDelegate();
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
PortDelegate proc_PORTGETDATA = new PortDelegate(getComData);
IAsyncResult async_PORTGETDATA = proc_PORTGETDATA.BeginInvoke(null, null);
}
private List ReceBuffer = new List(4096);//串口接收一级缓存,默认分配一页内存并始终不超过
private byte[] DataTemp = new byte[10];//从一级缓存拷贝到二级缓存
private List DataBuf = new List(1000);//串口接收二级缓存,默认分配1000并始终不超过
private byte[] DataTemp2 = new byte[10];//从二级缓存拷贝出来分析
private byte[] DataAnalyBuf = new byte[8];
public void getComData()
{
try
{
int n = serialPort_port.BytesToRead;
byte[] Receive = new byte[n];
serialPort_port.Read(Receive, 0, Receive.Length);
bool DataCatched = false;//数据可以分析的标志
//缓存数据
ReceBuffer.AddRange(Receive);
//完整性判断
while(ReceBuffer.Count >= 10)
{
////查看帧首和尾数据,判断准确性
//这里可以写成对数据的校验如CRC
if (ReceBuffer[0] == 0x50 && ReceBuffer[9] == 0x42)
{
ReceBuffer.CopyTo(0, DataTemp, 0, 10);
DataBuf.AddRange(DataTemp);
DataCatched = true;
ReceBuffer.RemoveRange(0, 10);//获得一条正确的数据,删除缓存
}
else
{
ReceBuffer.RemoveAt(0);//不是数据头,删除数据
}
}
//分析数据
if (DataCatched == true)
{
while (DataBuf.Count > 0)
{
DataBuf.CopyTo(0,DataTemp2,0,10);
在这里写自己的数据分析
DataBuf.RemoveRange(0, 10);
}
}
} catch { }
}