您好我一直致力于串口数据接收事件处理程序,我有一个Windows窗体,我每隔1ms连续接收数据,数据格式是$,0,0,0,0,0,1,0, 0,0,0,............... 0。这里$ - 表示框架的开始和之后是包含0的72位数据,72位中的特定位是1表示错误。在消息格式中,1表示错误,0表示没有执行某些操作的错误。所以我必须从串口读取数据并将其保存在一个数组中。保存数据后,我必须查找美元以指示帧的开始和1的计数,我可以相应地添加事件。 $,0,1,0,0,0 .... 0,0,0, - 72位宽的消息,消息帧中的1表示设备中的错误,因此相应的事件。那么任何人都可以帮我解决这个问题。
我的代码:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
List<byte> dataBuffer = new List<byte>();
var sp = (SerialPort)sender;
var indata = sp.ReadChar();
if (indata == 0x24 && dataBuffer.Count == 0)
{
while (serialPort1.BytesToRead > 0)
dataBuffer.Add((byte)serialPort1.ReadByte());
ProcessBuffer(dataBuffer);
dataBuffer.Clear();
}
}
int g=0;
private void ProcessBuffer(List<byte> comBuffer)
{
byte[] dataSend = new byte[serialPort1.BytesToRead];
for (int c = 0; c <= 72; c++)
{
if (comBuffer[c] == 0x01)
{
g = c;
}
}
}
答案 0 :(得分:2)
您假设您将在DataReceived事件处理程序中获得所有字节(或位)。你不会,当只有几个字节可用时它会触发。您需要应对这一点,至少通过在调用之间保持缓冲区。像这样:
private List<byte> dataBuffer;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs ek) {
var sp = (SerialPort)sender;
if (dataBuffer == null) {
// Looking for start byte
if (sp.ReadByte() != 0x24) return;
dataBuffer = new List<byte>();
}
while (sp.BytesToRead > 0) {
dataBuffer.Add(sp.ReadByte());
if (dataBuffer.Count == 72 / 8) {
// Got all bytes (or bits, it isn't clear), process it
var buf = dataBuffer;
dataBuffer = null;
ProcessBuffer(buf);
break;
}
}
}
你可能需要修复“足够的位”状态,你的问题并不清楚。 List不是那么漂亮,但它是确保数据在处理时保持稳定的一种非常好的方法,即使您对UI线程进行BeginInvoke也是如此。只有在确定只有一个线程可以同时访问它时,才用byte []替换。