串行通信中的拆分消息
本文关键字:拆分 消息 通信 | 更新日期: 2023-09-27 18:21:31
我是串行通信的新手。我读了不少教程,我想做的大部分都是工作,但我有一个关于C#串行通信的问题。我有一个微控制器,它不断地通过串行线发送数据。数据列表的格式如下:bxxxxixx.xx,xx.xx*其中x表示不同的数字、+或-符号。在某些时候,我想从电脑上的C#程序中读取这些信息。我遇到的问题是,即使我在使用ReadTo("*");我以为这会读到*字符之前的所有内容。如何确保收到的信息完整?
谢谢你的帮助。
public string receiveCommandHC()
{
string messageHC = "";
if (serialHC.IsOpen)
{
serialHC.DiscardInBuffer();
messageHC = serialHC.ReadTo("*");
}
return messageHC;
}
我不知道你为什么这么做,但你在读取之前丢弃了缓冲区中串行端口中的所有东西,所以如果计算机当时已经收到"bxxx",你就把它扔掉,只会读取"xixx.xx,xx.xx"。
您几乎总是会在串行通信中发现数据消息(除非非常小)是被拆分的。这主要取决于通信速度和从端口检索数据的点
通常,您会将代码设置为在单独的线程中运行(以帮助防止影响代码其余部分的性能),当收到完整的消息时,该线程会引发事件,并接收完整的消息进行传输。读写功能由工作线程处理(串行通信流量很慢)。
您需要一个读和写缓冲区。它们应该足够大,可以保存几个周期的数据。
将从输入读取的数据附加到读取缓冲区的末尾。让读取缓冲区从缓冲区开始循环读取完整消息。
根据使用的协议,通常会有一个数据开始,可能还有一个数据结束指示符,还有一个消息大小(这可能是固定的,同样取决于您的协议)。我从您的协议中了解到,消息的开始字符是'b'
,消息的结束字符是'*'
。丢弃邮件起始字符('b')前面的所有数据,因为这是一条不完整的邮件。
当找到完整的消息时,将其从缓冲区的前面剥离,并引发一个事件来指示其到达。
发送数据也会运行类似的过程,只是您可能需要拆分消息,因此要发送的数据会附加到缓冲区的末尾,并且从一开始就读取正在发送的数据。
我希望这能帮助你理解如何处理串行通信。
正如Marc所指出的,你目前正在以一种会引发问题的方式清理缓冲区。
编辑
正如我在评论中所说,我不识别serialHC,但如果处理原始数据,那么可以考虑使用SerialPort
类。关于如何使用它的更多信息和一个示例(大致使用了我上面描述的过程)可以在这里找到。
我猜你实际上得到的是命令的结束,也就是说,你得到的不是b01234.56.78.9
(省略最后的*
),而是.56.78.9
。这是因为您丢弃了输入缓冲区。不要那样做。您无法知道此时(读取之前)的状态,因此丢弃缓冲区是错误的。拆下serialHC.DiscardInBuffer();
线路。