0

嗨,我一直在研究串口数据接收事件处理程序,我有一个 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;
                 }
             }


         }                                                                                                                             
4

1 回答 1

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 不是那么漂亮,但它是确保数据在处理时保持稳定的一种非常好的方法,即使您 BeginInvoke 到 UI 线程也是如此。仅当您确定只有一个线程会同时访问它时,才用 byte[] 替换。

于 2012-10-26T10:09:07.263 回答