问题描述
在 STM32L4 上使用 CAN 时,我尝试发送三种不同数据类型的数据,即 float、bool 和 float 值。因为在一条消息中可以发送 8 个字节,所以我在一条消息中发送的所有三个数据。
我的数据看起来像
float tf;
uint16_t sl;
bool status_tf;
bool status_sl;
如果我能得到一些指导就太好了,我如何在单个 CAN 消息中组合所有三种数据类型?
直到现在,我都尝试使用带有打印格式说明符的 sprintf()
。并将组合结果存储在 char TxData[8];
中,但没有得到任何富有成效的结果。
要发送数据,使用标准 HAL_CAN_AddTxMessage()
。
HAL_CAN_AddTxMessage(&hcan1,&TxHeader,TxData,&TxMailbox);
解决方法
如何在单个 CAN 消息中组合所有三种数据类型?
乍一看,人们可能会考虑使用 struct
来保存所有数据,然后将其发送。
// First idea,but is it too big?
typedef struct {
float tf;
uint16_t sl;
bool status_tf;
bool status_sl;
} my_data;
由于填充,my_data
的大小可能超过 8 个字节,bool
可能超过 1 个字节。
考虑使用 memcpy()
来处理对齐问题。一个好的编译器会为如此小的副本发出传出代码。我会将 bool
分配给 charTxData[6]
(& 7) 以应对宽 bool
。仅分配 0 或 1 的值。
unsigned char TxData[8];
memcpy(&charTxData[0],&tf,4);
memcpy(&charTxData[4],&sl,2);
charTxData[6] = status_tf;
charTxData[7] = status_sl;
HAL_CAN_AddTxMessage(&hcan1,&TxHeader,TxData,&TxMailbox);
要恢复数据,请反向复制。
Pedantic 代码还会检查尺寸:
_Static_assert(sizeof tf == 4,"Unusual tf size");
_Static_assert(sizeof sl == 2,"Unusual sl size");
如果 uint16_t
和/或 float
或 float
编码的字节序可能不同,则需要额外的代码。