我正在开展涉及通讯的项目。我希望能够将结构和类型转换为字节以准备传输。不幸的是,字符串不适合我。
我使用的标准具有以下定义:
uint8_t address;
uint8_t function;
uint8_t startAddressHi;
uint8_t startAddressLo;
uint8_t numberOfRegistersHi;
uint8_t numberOfRegistersLo;
能够将强制转换为uint8_t
并简单地一次性传输整个结构会很好,但问题是Hi
和startAddress
字节{ {1}}指数较低。我希望有一些鲜为人知的方法来改变定义的字节顺序:
numberOfRegisters
再次,正如我所定义的那样,我的联盟,结束了。
我无法访问网络库中的typedef union{
struct rturxfields{
/* header */
uint8_t address;
uint8_t function;
/* data */
uint16_t startAddress; // <= needs some special sauce
uint16_t numberOfRegisters;
}RtuRxFields;
struct rturxfieldbytes{
/* header */
uint8_t address;
uint8_t function;
/* data */
uint8_t startAddressHi;
uint8_t startAddressLo;
uint8_t numberOfRegistersHi;
uint8_t numberOfRegistersLo;
}RtuRxFieldBytes;
uint8_t array[RX_FRAME_LENGTH];
}RtuRxFrame;
和类似内容。在做了更多阅读之后,我想我会简单地删除htons()
结构并创建实用程序函数RtuRxFields
以便干净地检索地址。
答案 0 :(得分:2)
您可以做的一件事是使用htons
和ntohs
来转换主机字节顺序(取决于机器)和网络字节顺序(大端)之间的16位值。写入16位值时,将它们传递给htons
以按正确顺序放置字节。
myunion.RtuRxFields.numberOfRegisters = htons(5);
如果您无法访问这些功能,可以使用位移来获取高字节和低字节,并在相关字段中单独写入:
uint16_t registers = 5;
...
myunion.RtuRxFieldBytes.numberOfRegistersHi = (registers >> 8) & 0xff;
myunion.RtuRxFieldBytes.numberOfRegistersLo = registers & 0xff;
由于结构填充,在网络上发送结构可能会有问题。两台不同机器上的两个不同的编译器可以使相同的结构在每个机器上具有不同的大小。有关详细信息,请参阅this guide。