在串行通信中拆分消息

时间:2012-01-27 08:14:00

标签: c# serial-port packets

我是串口通讯的新手。我已经阅读了相当多的教程,而我正在尝试做的大部分工作都是有效的,但我对C#的串行通信有疑问。我有一个微控制器,它通过串行线不断发送数据。数据采用以下格式: bxxxxixx.xx,XX.XX * 其中x代表不同的数字,+或 - 符号。 在某些时候想要从我的PC上的C#程序中读取这些信息。我遇到的问题是,即使我正在使用,我的消息似乎也会被随机分割 ReadTo( “*”); 我以为这会读取*字符的所有内容。 如何确保收到的邮件完整?

感谢您的帮助。

    public string receiveCommandHC()
    {

        string messageHC = "";
        if (serialHC.IsOpen)
        {
            serialHC.DiscardInBuffer();
            messageHC = serialHC.ReadTo("*");

        }
        return messageHC;
    }

3 个答案:

答案 0 :(得分:3)

我不确定你为什么要这样做,但是你在读取之前就丢弃了串口缓冲区中的所有内容,所以如果计算机已经收到了“bxxx”,你就把它扔掉你只会阅读“xixx.xx,xx.xx”。

答案 1 :(得分:1)

我会猜测你实际上是在获得命令的结束,即不是获得b01234.56.78.9(省略最后的*),而是得到(说).56.78.9。那是因为你丢弃了输入缓冲区。不要那样做。你无法知道那一点(就在读取之前)的状态,所以丢弃缓冲区是完全错误的。删除serialHC.DiscardInBuffer();行。

答案 2 :(得分:1)

您几乎总能在串行通信中发现数据消息(除非非常小)被拆分。这主要取决于通信速度以及从端口检索数据的时间点。

通常,您将代码设置为在单独的线程中运行(以帮助防止影响其余代码的性能),这会在收到完整的消息时引发事件并且还会传输完整的消息。读写功能由工作线程处理(串行通信流量很慢)。

您需要一个读取和写入缓冲区。这些应该适合大型数据保存几个周期。

将从输入读取的数据附加到读取缓冲区的末尾。从缓冲区的起始处循环读取读缓冲区以获取完整的消息。

根据所使用的协议,通常会有数据启动,也可能是数据结束指示符,某处是消息大小(这可能是固定的,同样取决于您的协议)。我从您的协议中收集消息开始字符为'b'且消息结束字符为'*'。丢弃消息开始字符('b')之前的所有数据,因为这是来自不完整的消息。

当找到完整的消息时,将其从缓冲区的前面剥离并发出一个事件以指示其到达。

运行类似的过程来发送数据,除了您可能需要拆分消息,因此要发送的数据被附加到缓冲区的末尾,并且从开始读取正在发送的数据。

我希望这有助于您了解如何应对串行通信。

正如Marc所指出,你目前正在以一种会导致问题的方式清理你的缓冲区。

修改

正如我在评论中所说,我不认识serialHC,但如果处理原始数据,那么请查看使用SerialPort类。可以找到有关如何使用它的更多信息和示例(大致使用我上面描述的过程)here