2012-08-08 40 views
2

我对C语言比较熟悉,最近我被要求做C#串行通信。 下面是我从COM端口接收数据代码:我可以做C#中的串行端口通信的计时器循环和超时?

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; 
     } 
    } 
} 

以上是我收到开头的0×01数据的方式,并结束于0x04。

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

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

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

+0

您的超时机制将无法按预期工作。您应该只在您未收到数据时增加计时器,并在收到数据时重置计时器。在当前实现中,即使您收到了100个字节,也会发生超时。 – PVitt 2012-08-08 10:44:52

回答

2

我想你可能有兴趣使用事件处理程序处理来自串口的数据。在.NET SerialPort类,你可以注册为接收数据的事件处理程序:

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(); 
} 

使用这种类型的模式,你不必循环,你刚才设置的阈值你需要,当串行端口为你准备好多个字节时,让框架调用你的事件处理程序。

希望这有助于我完全没有错过你的观点。 :)

+0

感谢您的建议@hmqcnoesy。但似乎用你的方式将收到所有的数据,无论如何。我如何使用你的方式进行数据过滤?我只需要0x01和0x04之间的数据,其他的只是垃圾。 – Coolguy 2012-08-08 02:47:49

+0

@Coolguy您可以将ReceivedBytesThreshold设置为1.然后您的事件处理程序将触发每个遇到串行端口的字节。然后,您可以在该事件处理程序中拥有过滤逻辑。 – hmqcnoesy 2012-08-08 02:50:06

+0

已注意。我试过你的建议。但是为什么当我输入sp.DataReceived + = new SerialDataReceivedEventHandler(DataReceivedHandler);有一个错误。这条线有3个错误。 1.类,结构体或接口成员声明中的标记'+ ='无效。 2.方法必须有返回类型。 3.标识符预计 – Coolguy 2012-08-08 02:55:27

1

ReadByte是一个同步呼叫。它只会在有字节读取时返回。

要让你尝试自己动手,你可以检查可用的数据读取之前:

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

除此之外,我更喜欢异步读取作为hmqcnoesy建议。