2

我更熟悉 C 语言,最近有人要求我用 C# 进行串行通信。下面是我从 COM 端口接收数据的代码:

public void RxData()
{
    int i = 0;
    int Data;
    bool StartRx = false;
    int timer;

    while (true)
    {
        Data = sp.ReadByte();
        if (Data == 0x01)
        {
            StartRx = true;
        }
        if (StartRx == true)
        {
            RxBuffer[i++] = Data;
        }
        if (Data == 0x04)
        {
            RxChkSum = RxBuffer[i - 2];
            break;
        }
        timer++;
        if(timer>100) 
        {
            timer = 0;
            break;
        }
    } 
}

以上是我接收以 0x01 开始并以 0x04 结束的数据的方式。

我正在增加一个计时器以计数到 100 并退出 while 循环,以防我没有收到任何数据。有点像超时。

但似乎计时器不起作用。当我没有收到任何数据时,我的程序就永远停留在 while 循环中。

我知道这是我们在嵌入式 c 编程中编写的方式。但这是用 C# 编写的正确方法吗?

4

2 回答 2

2

我认为您可能对使用事件处理程序处理来自串行端口的数据感兴趣。在 .netSerialPort类中,您可以为接收到的数据注册一个事件处理程序:

var sp = new SerialPort("COM1") {
    BaudRate = 9600,
    Parity = Parity.None,
    StopBits = StopBits.One,
    DataBits = 8,
    Handshake = Handshake.None
};

sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

您还可以在ReceivedBytesThreshold上设置属性,该属性SerialPort确定您的事件处理程序何时被触发。

然后,您只需设置事件处理程序以读取数据并使用它执行您需要的操作:

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string data = sp.ReadExisting();
}

使用这种类型的模式,您不必循环,只需设置所需的阈值,并在串行端口为您准备好那么多字节时让框架调用您的事件处理程序。

希望这会有所帮助,我并没有完全错过你的观点。:)

于 2012-08-08T02:42:26.900 回答
1

ReadByte是同步调用。它只会在有字节读取时返回。

为了让您尝试开始工作,您可以在阅读之前检查可用数据:

if(sp.BytesToRead > 0)
{
    Data = sp.ReadByte();
}

除此之外,我更喜欢hmqcnoesy建议的异步阅读。

于 2012-08-08T10:41:57.590 回答