Modbus字节序说明 用littly endine byte swap 解析寄存器
最近做ModBus TCP方面的测试有点多,尽管对于ModBus协议算是比较了解了,也经常知道字节传输序列的不同对工程师带来了很多不必要的麻烦,这不是一个技术难题,仅仅只是过去各家各户开发遗留下来的标准统一问题,所以这里写下这篇文章作为备忘。
在Modbus通信中,目前我们主要有16bit(AB)、32bit(AB CD)和最新的64bit(AB CD EF GH)三种数据长度。每个字母代表一个字节。
针对16bit传输,只存在正序(AB)
或反序(BA)
两种方式,也就所谓的正序先传高位,以及反序先传低位,为什么会出现这样的现象,可以联系堆栈处理的方式,不过这个不重要。
更多的应用场景针对的是双字32位数据传输。那么同样的正序(ABCD)
以及反序(DCBA)
似乎就够用了,但是却还有字节交换这样的问题,所以你经常会看到SWAP函数,这样的我们衍生出了以下四种排序方式。
Big-endian :ABCD Little-endian :DCBA Big-endian byte swap :BADC Little-endian byte swap :CDAB
对于32bit的Real类型:对应十六进制:ABCD。
1. Big-endian: 大端模式,正序。即:大端排序,先传递高位A依次传递到低位D。压入发送队列发送。
所以在通讯中,收发到的数据不对,先要做的就是确定确定数据类型,其次要确定数据传输时的字节序是如何的,这有确保了这两点的正确性,才可以正确的解析出数据。
2. Little-endian:小端模式,正序。即:依次从低位到高位。压入发送队列,发送。
3. Big-endian byte swap: 大端模式,反序。先将寄存器内部字节交换,然后按照大端模式发送。
4. Little-edian byte swap : 小端模式,反序。 先将寄存器内部字节交换顺序,然后按照小端模式依次压入发送队列,发送。
float readModbusDataReal32bitBigMode(quint16 dataHighSectionABCDInD1, quint16 dataLowSectionDEFHInD2) { //55.23 (??) 0xEB85, (B\) 0x425C /* * float: ABCD。 小端模式交换字节:先发送的是低字节, CD AB 就是:(向左看)是压入发送队列的顺序。 modbus 中D1位置就是:CD, D2寄存器就是:AB 解析:字节数组char floatArray[4], 其中:3是高位,0是低位。 因此:因为是小端模式 则D1是floatArray中的[0,1]字节,且正序,D是0字节,C是1字节。 D2是flaotArray中的[2,3]字节,正序,A是3字节,B是2字节。 */ QByteArray array0xABCDEFGH;//4字节 array0xABCDEFGH.resize(4); array0xABCDEFGH[3] = (dataLowSectionDEFHInD2 & 0xFF00) >> 8; array0xABCDEFGH[2] = (dataLowSectionDEFHInD2 & 0xFF); array0xABCDEFGH[1] = (dataHighSectionABCDInD1 & 0xFF00) >> 8; array0xABCDEFGH[0] = (dataHighSectionABCDInD1 & 0xFF); float tempFloat32; memcpy(&tempFloat32, array0xABCDEFGH.data(), array0xABCDEFGH.length()); return tempFloat32; }
void writeModbusDataReal32bitBigMode(float realData, quint16* dataHighSectionABCD, quint16* dataLowSectionDEFH) { //一个float占4个字节 AB CD. D是低端字节。 // 小端模式,交换字节:先发送的是低字节, CD AB int leng4Byte = sizeof(realData); QByteArray array0xABCDEFGH;//4字节 array0xABCDEFGH.resize(leng4Byte); memcpy(array0xABCDEFGH.data(), &realData, leng4Byte); // quint16 temp16; temp16 = array0xABCDEFGH[1] << 8 & 0xFF00; temp16 |= array0xABCDEFGH[0] ; *dataHighSectionABCD = temp16; temp16 = 0; temp16 = array0xABCDEFGH[3] << 8 & 0xFF00; temp16 |= array0xABCDEFGH[2]; *dataLowSectionDEFH = temp16; }
标签:说明,AB,正序,字节,array0xABCDEFGH,发送,Modbus,endian From: https://www.cnblogs.com/JohnnyLei/p/18180046