0

我是 C# 和串行通信领域的新手。阅读了一些教程后,我设法使通信正常工作。我在这里问了另一个类似的问题,但我认为我问的问题不正确。我遵循了上一个问题中给出的建议并稍微更改了我的代码,以便我现在从我的微控制器发送一条看起来像这样的串行消息:

SxxxxxxxxxxxxxxxxxxxxxxxxE

x 代表不同的数字,加号和减号以及逗号。我发送的字符串将始终具有相同的长度,并且始终以 S 开头并以 E 结尾(如果这不好,我可以更改它)。我遇到的问题是,当我尝试读取串行线路时,我一次只能收到部分消息,所以是这样的:

Sxxxxxxx
xxxxx
xxxxESxxx

我从微控制器连续发送此信息,但只想在特定时间访问它,所以换句话说,我正在尝试编写一个函数来接收消息的所有部分,将其放回一起,然后从我的功能。问题是我现在不知道该怎么做。

任何帮助将不胜感激!

这是我一直在玩的代码:

    SerialPort serialHC = new SerialPort(); // serial connection dealing with Hand Controller

     public string receiveCommandHC()
    {

        string messageHC = "";
        if (serialHC.IsOpen)
        {
            //serialHC.DiscardInBuffer();
            //messageHC = serialHC.ReadLine();
            messageHC = serialHC.ReadTo("*");
            //tempMsgHC = serialHC.ReadTo("*");
            //i = tempMsgHC.IndexOf("S");
            //tempMsgHC.Remove(0,i);
            //messageHC = tempMsgHC;

            //serialHC.Read(bufferHC = new byte[serialHC.BytesToRead], 0, serialHC.BytesToRead);
        }
        return messageHC;

我曾经让消息的结尾是“*”

刚刚尝试按照这里的示例进行操作,这就是我从中得到的。 收到串行消息

这就是我要发送的内容(使用 Putty 进行检查) 在此处输入图像描述

4

1 回答 1

2

当您收到数据时,您似乎无法真正采取行动。您不一定会收到完整的消息。因此,您需要缓冲您阅读的内容,直到您检测到您有完整的消息。

可能有更有效的方法可以做到这一点,但我对它们不太熟悉。所以这里有一个简单的算法来处理这个问题。它可以实现为一个简单的状态机。

初始化:

  1. 分配一个足够大的缓冲区以容纳可能的最大消息。这将在您读取传入数据时保存消息,直到您准备好处理它。

  2. 分配一个固定大小的缓冲区来读取数据。

  3. 进入“等待消息”状态。

等待消息:

  1. 阅读每个符号,直到找到“S”或到达消息末尾。
  2. 如果找到“S”,则进入“正在阅读消息”状态。
  3. 如果未找到“S”,则等待下一条消息。

阅读留言:

  1. 将数据中的每个符号复制到消息缓冲区中,直到找到“E”或到达消息末尾。
  2. 如果找到“E”,则安排要处理的消息缓冲区的内容,将其清除并进入“等待消息”状态。
  3. 如果未找到“E”,请等待下一条消息。

下面是一些捕捉算法本质的代码:

enum ReadState { Waiting, Reading, Finished }
static string ReadMessage(SerialPort port)
{
    var messageBuffer = new StringBuilder("S");
    var state = ReadState.Waiting;
    while (state != ReadState.Finished)
    {
        switch (state)
        {
        case ReadState.Waiting:
            if (port.ReadChar() == 'S')
            {
                state = ReadState.Reading;
            }
            break;
        case ReadState.Reading:
            messageBuffer.Append(port.ReadTo("E"));
            state = ReadState.Finished;
            break;
        }
    }
    return messageBuffer.ToString();
}

我最初是在一个更低的层次上考虑这个的,这个SerialPort类似乎有一些方法可以让这更容易一些。

于 2012-01-28T07:10:38.917 回答