在Modbus RTU消息中编辑浮点数(实数)和32位数据(转)

在Modbus RTU消息中编辑浮点数(实数)和32位数据

豆腐包子 2019-09-04 13:29:56 1551 收藏 2
展开
目录
字节顺序的重要性
确定字节顺序
实际帮助
在使用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.i32 N/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.i16 N/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-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.float 123456.00 1.float-2.i16 0x2000 0x47F1
0xF147 0x0020 2.i16-1.float-s 123456.00 1.float-2.i16-s 0xF147 0X0020
0x0020 0xF147 2.i16-1.float-sb 123456.00 1.float-2.i16-sb 0x0020 0xF147
0x47F1 0x2000 2.i16-1.float-sw 123456.00 1.float-2.i16-sw 0x47F1 0x2000
请注意,不同的字节和字顺序需要使用相应的FieldServer函数移动。选择正确的功能移动后,可以在两个方向上转换数据。

在互联网上可用的许多十六进制到浮点转换器和计算器中,很少有实际允许操作字节和字顺序。一个这样的实用程序可以在这里下载。该实用程序的十进制浮点值为123456.00,如下所示:


然后可以交换字节和/或字来分析Modbus RTU主设备和从设备之间可能存在的潜在字节序问题。
————————————————
版权声明:本文为CSDN博主「豆腐包子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37827925/article/details/100532669

猜你喜欢

转载自www.cnblogs.com/NickShen86/p/12809201.html
今日推荐