Modbus TCP Float32大端字节序解析异常技术求助
问题原因解析
你遇到的字节序问题,本质是混淆了Modbus寄存器级的字节序和标准Float32字节序的差异:
- 标准Float32大端(BE)的100对应的字节流是
0x42 0xC8 0x00 0x00(即你测试的<Buffer 42 c8 00 00>),这是按连续字节从高到低排列。 - 但Modbus传输Float32时,会将4字节拆分为两个16位寄存器:
- Float32的高16位是
0x42C8,低16位是0x0000 - 你的设备采用低地址寄存器存储Float32低16位的方式,所以传输时先发送低16位寄存器的字节(大端:
0x00 0x00),再发送高16位寄存器的字节(大端:0x42 0xC8),最终得到你收到的<Buffer 00 00 42 c8>
- Float32的高16位是
为什么先swap16再swap32能解决?
一步步拆解过程:
- 原始buffer:
<Buffer 00 00 42 c8> - 第一步
swap16():交换每个16位单元内的字节,得到<Buffer 00 00 c8 42>(相当于把每个寄存器的字节顺序反转,变成小端寄存器) - 第二步
swap32():交换整个4字节的字节顺序,得到<Buffer 42 c8 00 00>(正好匹配标准Float32大端的字节流)
不过更直接的方式是交换两个16位寄存器的位置,不需要两次swap:
const received = Buffer.from([0,0,66,200]); // <Buffer 00 00 42 c8> // 交换前两个字节和后两个字节 const corrected = Buffer.concat([received.slice(2), received.slice(0,2)]); // <Buffer 42 c8 00 00> console.log(corrected.readFloatBE()); // 输出100
总结
Modbus中Float32的“大端”通常指单个寄存器内部是大端字节序,但寄存器之间的排列顺序由设备决定(低字在前或高字在前)。你的设备属于低字在前的情况,因此需要将两个16位寄存器的字节块整体交换,才能匹配标准Float32大端的字节顺序。
内容的提问来源于stack exchange,提问作者ralphcom
相关产品推荐
相关产品推荐

