当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]这种方法虽然可行,但容易出问题。当我编写裸机轮询循环(不使用中断或DMA)时,发现了一个严重的问题:如果接收端的微控制器正在执行其他任务而错过单个字节——即典型的缓冲区溢出错误——整个文本流就会发生偏移。

我为何开发它(问题所在)

如果你曾经连接过两个微控制器——比如ESP32和STM32——你很可能使用过UART。通常,最简单的数据传输方式是通过来回发送纯文本字符串。

这种方法虽然可行,但容易出问题。当我编写裸机轮询循环(不使用中断或DMA)时,发现了一个严重的问题:如果接收端的微控制器正在执行其他任务而错过单个字节——即典型的缓冲区溢出错误——整个文本流就会发生偏移。

想象一下这样的场景:你的ESP32在发送温度和湿度数据。如果丢失了一个字节,接收端的字符串解析器就会混乱。它可能将一半的温度值和一半的湿度值读取为一个整数,从而将完全损坏的数据保存到变量中。

BAVA是什么(解决方案)

我希望有一种更安全的方式,在不依赖复杂库的情况下实现线路上的数据传输。于是,我开发了BAVA。它是一个轻量级的C语言库,直接位于标准UART之上,为通信添加结构化和安全性。

BAVA 不会发送文本,而是将你的变量打包成整洁的二进制帧。

[起始标记] -> [命令] -> [ID] -> [长度] -> [有效载荷] -> [CRC-16]

•起始标记(0xAA):告诉接收方有新数据包到达。

•命令:告知接收方这是“写入”(保存这些数据)还是“读取”请求。

•ID:你特定变量的唯一十六进制标签。

•长度:有效载荷中确切包含的字节数。

•有效载荷:实际的原始二进制数据(你的结构体或变量)。

•CRC-16:一种数学校验和,用于验证是否有字节损坏或丢失。‘

1:定义数据与硬件设置

首先,ESP32 和 STM32 需要就数据格式达成一致。我们为遥测数据定义一个标准的 C 结构体。

接着,我们告诉 BAVA 如何与特定硬件通信。我们编写一个简单的发送回调函数,并将其传递给初始化函数。

2:注册变量(对象字典)

在此处,BAVA 取代了字符串解析。我们不再发送如“TEMP”这样的名称,而是将传感器结构体的内存地址映射到特定 ID(例如 0x01)。这一操作在两个微控制器上都执行。

3:数据传输(ESP32)

当ESP32想要发送新的传感器数据时,无需使用snprintf格式化字符串,只需更新本地的结构体,并告诉BAVA发送该特定ID即可。

BAVA会自动将结构体封装成[Start][Cmd][ID][Len][Data][CRC]帧,并通过UART线传输。为防止实际的传感器数据意外与起始标记匹配导致错误,BAVA会自动使用转义字节(0x07)安全地编码有效载荷。

4:无解析接收(STM32)

在STM32端,主轮询循环监控UART硬件。每当接收到一个字节,就会直接传入BAVA的非阻塞状态机中。

随着字节不断流入,状态机检查长度并计算CRC-16。如果硬件丢失了某个字节,CRC将失败,此时数据包会被安全忽略。

但如果数据包有效,BAVA会查找ID(0x01),并将有效载荷直接写入STM32传感器结构体的指针位置。

整个过程无需字符串解析,我们只需检查变量是否已更新,若已更新,则可立即向ESP32发送确认(ACK)数据包。

通过将十六进制ID直接映射到内存指针,BAVA能够即时更新变量。它完全不使用动态内存(无malloc调用),因此在裸机系统上具有高度的确定性。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭