【问题标题】:Serial Port DataReceived firing multiple timesSerial Port DataReceived 多次触发
【发布时间】:2014-11-24 17:19:55
【问题描述】:

我正在开发一个与 FPGA 设备通信的 winforms 应用程序。由于该设备仍在开发中,我正在尝试使用 com0com (http://com0com.sourceforge.net/) 和另一个 winforms 应用程序作为模拟器对其进行模拟。

我正在从我的应用程序向模拟器发送一个 44 字节的字节数组:

CC AA 01 28 09 2A 0C 00 01 FF 00 FA 02 FF 01 5E 03 FF 01 C2 04 FF 02 26 05 FF 02 8A 06 FF 02 EE 07 FF 03 52 08 FF 03 B6 09 FF 04 1A

前 4 个字节是标题,第四个字节包含后面的字节数。在这种情况下,40=0x28。 API 规范中没有终止值。以下是我处理 DataRecieved 事件的方式:

void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    int byte_count = 0;
    int read_count = 0;
    while (comPort.BytesToRead > 0)
    {
        byte_count = comPort.BytesToRead;
        byte[] byteTemp = new byte[byte_count];
        read_count = comPort.Read(byteTemp, 0, byte_count);
    }
    byte[] byteBuffer = new byte[read_count];
    int intNumBytes2read = byteBuffer[3];

    // do other stuff
}

我的问题是当事件触发时模拟器并不总是接收到整个有效负载。事实上,每次我将数据从我的应用程序发送到模拟器时,该事件通常会触发不止一次。我对该主题的研究表明这是一个常见问题,我需要创建某种排队机制。由于我有限的 C# 经验,我很难理解如何做到这一点。

任何建议将不胜感激。

【问题讨论】:

    标签: c# winforms serial-port


    【解决方案1】:

    您需要一个状态机来跟踪您在接收消息方面的进度。可能是这样的:

    private int state;
    private byte[] payload;
    private int payloadIndex;
    
    private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
        while (comPort.BytesToRead > 0) {
            byte b = (byte)comPort.BaseStream.ReadByte();
            switch (state) {
                case 0: 
                    if (b == 0xcc) state++;
                    else protocolViolation("Bad header, expected 0xcc");
                    break;
                case 1:
                    if (b == 0xaa) state++;
                    else protocolViolation("Bad header, expected 0xaa");
                    break;
                case 2:
                    if (b == 0x01) state++;
                    else protocolViolation("Bad header, expected 0x01");
                    break;
                case 3:
                    payload = new byte[b];
                    payloadIndex = 0;
                    state++;
                    break;
                case 4:
                    payload[payloadIndex++] = b;
                    if (payloadIndex == payload.Length) {
                        processPayload(payload);
                        state = 0;
                    }
                    break;
            }
        }
    }
    
    private void protocolViolation(string why) {
        state = 0;
        Debug.WriteLine(why);
    }
    
    private void processPayload(byte[] payload) {
        // etc..
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      相关资源
      最近更新 更多