如何设计一个函数来识别“+IPD”何时从UART 到达?

How to design a function which identifies when "+IPD," is arrived from UART?

我正在使用 Tiva Launchpad EK-TM4C123GXL 和 ESP8266 WIFI 模块。

本模块收到wifi包后,通过UART口发送给单片机

ESP8266发送数据包(通过UART到uC)使用的格式是:

+IPD,n:xxxxx\r\nOK\r\n

其中:

例如:

+IPD,5:hello\r\nOK\r\n

这是我的情况:

我正在处理现有项目,我无法更改以下两点:

1- UART 模块已配置为在其接收 FIFO(16 字节)为 half-full 时生成中断。

2- 处理此中断的 ISR(中断服务程序):

现在,我必须用 C 语言编写这个名为 rx_data() 的函数。

所以,来自 ESP8266 模块的消息被传递给这个函数,rx_data(),一次一个字节,这个函数必须能够至:

我想按部就班,所以现在我在推理:

如何识别 +IPD, ,考虑到 一次只有一个字节 被传递给这个函数?

是时候制作状态机了。每次调用 rx_data 时,您都会更新状态机的状态,最终在某个时候您会知道您收到了字符串“+IPD”。

假设将从 UART 接收的字节作为参数传递给 rx_data

void rx_data(uint8_t byte)
{
    static uint8_t state = 0;
    if (byte == '+') { state = 1; }
    else if (state == 1 && byte == 'I') { state = 2; }
    else if (state == 2 && byte == 'P') { state = 3; }
    else if (state == 3 && byte == 'D') { state = 4; }
    else if (state == 4 && byte == ',') {
      state = 0;
      handleIPDMessage();  // we received "+IPD,"
    }
    else { state = 0; }
}

您可以看到当且仅当最后收到的字符是“+IPD”时才会调用 handleIPDMessage()

但是,您应该考虑编写一个更通用的状态机,它可以对行进行操作,而不是仅仅查找这个字符串。这可能会更容易编写并且更健壮。当接收到完整的行时,您将调用名为 handleLineReceived() 的函数来处理该行。该函数可以访问包含整行的缓冲区,并且可以以任何它想要的方式解析它。 (请注意,您永远不要写入超出该缓冲区末尾的内容。)

顺便说一下,我不会在 ISR 中加入那样的逻辑。通常最好保持 ISR 简单快速。如果您还没有这样做,请将字节存储到 ISR 中的循环缓冲区,然后在主循环中从循环缓冲区中读取,每次从循环缓冲区中读取一个字节,然后调用 [=11 之类的函数=] 上面描述的函数来处理字节。