gpt4 book ai didi

c - 如何设计一个函数来识别 "+IPD,"何时从 UART 到达?

转载 作者:太空宇宙 更新时间:2023-11-03 23:21:46 24 4
gpt4 key购买 nike

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

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

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

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

哪里:

  • n为数据包的长度(以字节为单位)
  • :表示下一个字节为第一个数据字节
  • xxxxx为数据包
  • \r\nOK\r\n 是 6 个字节,它们对我没用。

例如:

+IPD,5:你好\r\nOK\r\n

这是我的情况:

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

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

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

  • 只从 UARTDR(UART 数据寄存器)读取一个字节

  • 将其保存到一个变量中

  • 调用将处理该字节的函数(称为 rx_data())。

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

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

  • 识别标题+IPD,

  • 读取数据包长度n

  • 将数据包xxxxx(位于:字符之后,第一个\r字符之前)保存到一个缓冲区

  • 丢弃最后的字节 \r\nOK\r\n(这 6 个字节对我来说没用,但无论如何,我必须读取它们以将它们从 Receive FIFO 中移除)

我想一步一步来,所以现在我在推理:

如何识别 +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 中的循环缓冲区,然后在主循环中从循环缓冲区中读取,每次从循环缓冲区中读取一个字节,然后调用类似 的函数rx_data 上面描述的函数来处理字节。

关于c - 如何设计一个函数来识别 "+IPD,"何时从 UART 到达?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37580655/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com