在ModbusRTU消息中编辑浮点数(实数)和32位数据
⽬录
在使⽤Modbus RTU协议时常常会遇到要传输32位浮点型数据的情况。本⽂讨论如何解决传输浮点数的问题。
点对点的Modbus协议时RTU通信的常⽤选择。协议本⾝控制Modbus⽹络上每个设备的交互,设备如何建⽴已知地址,每个设备如何识别其消息以及如何从数据中提取基本信息。从本质上讲,该协议是整个Modbus⽹络的基础。
然⽽,这种便利并⾮没有⼀些复杂性,Modbus RTU消息协议也不例外。协议本⾝是基于具有16位寄存器长度的器件设计的。因此,在实现32位数据元素时需要特别注意。该实现决定使⽤两个连续的16位寄存器来表⽰32位数据或基本4字节的数据。在这4个字节的数据中,单精度浮点数据可以编码为Modbus RTU消息。
字节顺序的重要性
Modbus本⾝没有定义浮点数据类型,但⼈们普遍认为它使⽤IEEE-754标准实现了32位浮点数据。但是,IEEE标准没有明确规定数据有效载荷的字节顺序。因此,处理32位数据时最重要的考虑因素是数据
按正确顺序寻址。
例如,IEEE 754单精度32位浮点数标准中定义的数字123456.00如下所⽰:
各种字节排序的影响很⼤。例如,在“B A D C”序列中对表⽰123456.00的4字节数据进⾏排序,称为“字节交换”。当解释为IEEE 744浮点数据类型时,结果完全不同:
在“C D A B”序列中排序相同的字节称为“字交换”。同样,结果与原始值123456.00⼤不相同:
此外,“字节交换”和“字交换”基本上都会完全颠倒字节序列以产⽣另⼀个结果:
显然,在使⽤Modbus等⽹络协议时,必须严格注意内存字节在传输时的排序⽅式,也称为“字节顺序”。
确定字节顺序
根据Modbus应⽤协议规范V1.1.b,Modbus协议本⾝被声明为“big-Endian”协议:
“Modbus uses a “big-Endian” representation for addresses and data items. This means that when a numerical quantity larger than a single byte is transmitted, the most significant byte is sent first.”
Big-Endian是⽹络协议最常⽤的格式 - 实际上很常见,它也被称为“⽹络秩序”。
鉴于Modbus RTU消息协议是big-Endian,为了通过Modbus RTU消息成功交换32位数据类型,必须考虑主站和从站的字节顺序。许多RTU主设备和从设备允许特定的字节顺序选择,特别是在软件模拟单元的情况下。必须确保所有单元都设置为相同的字节顺序。
根据经验,设备的微处理器系列决定了它的字节顺序。通常,big-Endian样式(⾸先存储⾼位字节,然后是低位字节)通常在使⽤Motorola处理器设计的CPU中到。 little-Endian样式(⾸先存储低位字节,然后是⾼位字节)通常在使⽤Intel架构的CPU中到。关于哪种风格被认为是“倒退”,这是个⼈观点的问题。
但是,如果字节顺序和字节顺序不是可配置选项,则必须确定如何解释字节。这可以通过从从站请求已知的浮点值来完成。如果返回不可能的值,即具有两位数指数等的数字,则字节排序很可能需要修
改。
实际帮助
FieldServer Modbus RTU驱动程序提供多种功能移动,可处理32位整数和32位浮点值。更重要的是,这些函数移动考虑了所有不同形式的字节排序。下表显⽰了FieldServer函数移动,它将两个相邻的16位寄存器复制为32位整数值。
Function Keyword Swap Mode Source Bytes Target Bytes
2.i16-1.i32N/A[ a b ] [ c d ][ a b c d ]
2.i16-1.i32-s byte and word swap[ a b ] [ c d ][ d c b a ]
2.i16-1.i32-sb byte swap[ a b ] [ c d ][ b a d c ]
2.i16-1.i32-sw word swap[ a b ] [ c d ][ c d a b ]
下表显⽰了FieldServer函数移动,它将两个相邻的16位寄存器复制到32位浮点值:
Function Keyword Swap Mode Source Bytes Target Bytes
2.i16-1.ifloat N/A[ a b ] [ c d ][ a b c d ]
2.i16-1.ifloat-s byte and word swap[ a b ] [ c d ][ d c b a ]
2.i16-1.ifloat-sb byte swap[ a b ] [ c d ][ b a d c ]
2.i16-1.ifloat-sw word swap[ a b ] [ c d ][ c d a b ]
下表显⽰了FieldServer函数移动,它将单个32位浮点值复制到两个相邻的16位寄存器:
Function Keyword Swap Mode Source Bytes Target Bytes
1.float-
2.i16N/A[ a b c d ][ a b ][ c d ]
1.float-
2.i16-s byte and word swap[ a b c d ][ a b ][ c d ]
1.float-
2.i16-sb byte swap[ a b c d ][ a b ][ c d ]
1.float-浮点型变量float
2.i16-sw word swap[ a b c d ][ a b ][ c d ]
鉴于FieldServer函数的移动,32位数据的正确处理取决于选择合适的数据。观察这些FieldServer函数的以下⾏为在已知的单精度⼗进制浮点值123456.00上移动:
16-bit Values Function Move Result Function Move Result
0x2000 0x47F1 2.i16-1.float123456.00 1.float-2.i160x2000 0x47F1 0xF147 0x0020 2.i16-1.float-s123456.00 1.float-2.i16-s0xF147 0X0020 0x0020 0xF147 2.i16-1.float-sb123456.00 1.float-2.i16-sb0x0020 0xF147 0x47F1 0x2000 2.i16-1.float-sw123456.00 1.float-2.i16-sw0x47F1 0x2000
请注意,不同的字节和字顺序需要使⽤相应的FieldServer函数移动。选择正确的功能移动后,可以在两个⽅向上转换数据。
在互联⽹上可⽤的许多⼗六进制到浮点转换器和计算器中,很少有实际允许操作字节和字顺序。⼀个这样的实⽤程序可以在这⾥下载。该实⽤程序的⼗进制浮点值为123456.00,如下所⽰:
然后可以交换字节和/或字来分析Modbus RTU主设备和从设备之间可能存在的潜在字节序问题。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论