我有两块板:
- 主板(M板)
- 从板(S板)
M董事会应向S板发送请求,后者应回答。
奴隶的答案是一个结构:
typedef struct{
uint8_t userID;
uint8_t userPass;
uint16_t userData;
}UserTypeDef;
UserTypeDef User;
例:
M板通过发送命令GET_USER_INFO来询问用户的信息(结构)。 S板应将数据结构返回给M板。
M Board(Tx) - > GET_USER_INFO - > (Rx)S Board
S Board(Tx) - >用户 - > (Rx)M Board
问题是如何使用UART发送这样的结构?
答案 0 :(得分:3)
编写协议文档,明确定义如何通过网络媒体传输结构的内容。然后编写代码来实现协议。
传输结构/对象的代码是" serializing"数据。接收结构/对象的代码是"反序列化"。您可以通过Google获取有关各种序列化协议和技术的大量建议和示例。
如果你正在使用二进制协议,那么你可以序列化一个C结构,通过定义一个uint8_t指针指向结构中的第一个字节,然后传输字节,直到你传输了整个sizeof(struct)
。 但这种方法有一些缺陷,特别是如果您的发送和接收设备使用不同的微控制器和/或C编译器。如果一个微控制器使用不同的字节序,或者如果一个C编译器使用不同的结构填充规则,那么反序列化的数据可能会被破坏。
这就是为什么你必须编写一个明确定义每个字节的顺序和含义的协议文档。而且你不应该依赖你的C编译器来组织结构,就像你的协议一样。 C编译器可能会插入填充或使用错误的字节顺序。因此,您应该编写序列化和反序列化例程来解析网络协议消息中的每个字节,并将其复制到结构中的相应字节中,而不是简单地通过结构递增指针。
答案 1 :(得分:2)
最简单的方法是以二进制形式发送它。只要接收方知道发送方的字节顺序(并为其调整),您就可以一次性发送整个结构。这里的缺点是人类看到串口只会看到乱码,如果您的串口是7位而不是8位,它将无法工作。
第二个最简单的方法是将结构转换为十六进制,但仍然将其作为一个数据块发送(例如,如果你的结构是{25, 54, 16745}
,你可以发送19364169
,并有接收器将它分成字段。这种方法的缺点是它使用的字节数是第一种方法的两倍。
最困难,但最强大的是发送字段名称后跟值。这很好,因为查看序列的人很容易知道发生了什么,如果稍后在结构中添加一个字段,接收软件会在看到它无法识别的名称时抛出错误。因此,从上面的示例数据中,您可能会:
userID: 0x19, userPass: 0x36, userData: 0x4169
。这里的缺点是浪费了很多字节发送名称,所以如果你受到串行链接速度的限制,你可能不想这样做。
答案 2 :(得分:1)
保持可读性的最佳方法是以可读的形式对其进行编码。
这可以像使用sprintf
将字符串编码为字符串一样简单。
char buffer[BUFFER_LEN];
sprintf(buffer, "%i:%i:%i", user.userId, user.userPass, user.userData);
send_over_uart(buffer);