2024年5月9日发(作者:qq音乐最新版本下载安装)
iFix中MB1驱动器64位字交换浮点数的处理
0、看了KroHne流量计关于浮点数计算式后,方知本文原计算方法太麻烦,引用
新的计算方法对本文更正之。
一、问题的提出
对IFC050流量计进行读数据试验,首先使用Modscan32,读出数据要么瞬
时流量不对,要么累积值不对,查手册知,流量瞬时值为32位字交换浮点数,
累积值为64位字交换浮点数,分别适用不同的格式显示数据,它们都是正确的。
因为都是Modbus协议,所以我们认为iFix使用MB1驱动也能够正确读出数据。
但在实际使用iFix中MB1驱动器读IFC050流量计的累积值时,发现驱动
器关于64位浮点数只支持一个Float64,再无其它64位浮点数格式。同时在数
据库的数据块配置之硬件选项中,64位浮点数也只有一个Float64,再无其它
64位格式。照此配置,原本百万的数值在iFix显示为-0.0。就这还有一段话:
NOTE: The FIX database handles up to 32-bit values. Consequently,
64-bit values are converted to 32-bit before being stored in the process
database. 意思是数据库只支持32位,64位的数据进数据库前转换成32位。
似乎没法了!
联想到Float和WFloat是高低字位置交换了,而Modscan32读出的累积值
使用的是WFloat64,高低字交换了,这个问题实际上是数据存放顺序造成的。
那么,只要知道原始数据的存放方式,好像还可以通过脚本处理这一问题。
Modscan可以以各种方式显示数据,改变数据显示方式,很容易找到原始数
据的存储方式。
二、浮点数的表示
32位浮点数的标准格式IEEE754
31 30 23 22 0
S E
S(E-127)
M
其值为:x=(-1)×(1.M)
64位浮点数的标准格式IEEE754
63 62 52 51 0
S
其中:
S--尾数符号,0正1负;
E--阶码,采用移码表示(移码可表示阶码符号)。
E
S(E-1023)
M
其值为:x=(-1)×(1.M)
M--尾数,纯小数,小数点放在尾数域的最前面,采用原码表示。每位的权
值为2
(位号-52)
,
第51位权值是2
-1
=0.5, 第50位权值是2
-2
=0.25, 第49位权值
是2
-3
=0.125,......,依此类推。
三、实际数据分析
流量计的累积值存储在30009-300124个寄存器中,各自值分别为:
63-48位
47-32位
31-16位
16-0位
按照上述数据表示分析,30009=HH,30010=HL,30011=LH,30012=LL
而MB1的Float64按30009=HL,30010=HH,30011=LL,30012=LH处理。所
以用MB1的Float64读不出数据也就可以理解了。
四、问题的解决方案
在外部设备不能更改的条件下,通过调度和脚本可以解决这一问题。具体步
骤如下:
⑴ 在MB1驱动配置时,将一个64位浮点数定义成4个无符号整数;
⑵ 在数据库中定义4个0-65535的AI或者一个AR;
⑶ 在数据库中定义AO/AI,其设备选择SM2,不能用SIM;
⑷ 当这4个数任一个变化时,调用数据处理脚本,按照上述算式计算浮
点数,存放在AO/AI 中。
⑸ 具体计算式如下:
符号位: si = HH And 32768) / 32768
阶 码: ex = (HH And 32752) / 16
尾 数: ma = (((LL/ 65536+LH)/65536)+HL)/65536 + HH And 15)/16
处理脚本如下:
Dim F(4) As Long
Dim S, E As Integer
Dim M, MF As Double
Dim MT(10) As Double
'读入双精度浮点数的4个字,不管原始数据咋排列,在这里按最高字、次
高字、次低字、最低字的顺序排列
F(0) = 16687 ' readvalue("1.f64.f_0")
F(1) = 39434 'readvalue("1.f64.f_1")
F(2) = 23508 'readvalue("1.f64.f_2")
F(3) = 19541 'readvalue("1.f64.f_3")
S = (F(0) And 32768) / 32768
E = (F(0) And 32752) / 16
MT(1) = (F(0) And 15) / 16
MT(2) = F(1) / 16 / 65535
MT(3) = F(2) / 16 / 65535 / 65535
MT(4) = F(3) / 16 / 65535 / 65535 / 65535
MT(0) = MT(1) + MT(2) + MT(3) + MT(4)
M = MT(0) + 1
MF = ((-1) ^ S) * (2 ^ (E - 1023)) * M
tValue = MF
.f64.f_cv = MF
.f_cv = MF
执行结果如上;使用SIM驱动器的和使用SM2驱动器的
Fix32.f64的设置相同均为0-9999999999999.9。但执行结果值有差异,SIM驱
动有一个可显示范围,SM2驱动的值更准确,所以建议使用SM2,不建议使用SIM。
更正:使用SIM和SM2造成的数据差异不仅仅是因为驱动的原因,还有块
类型及其属性:都是AO,其值相同,AI可输出,由于SIM只有16位,SM232位,
故SIM的AI可输出精度肯定要差。(2016年1月27日更正)
郭振华 2014年9月3日
发布者:admin,转转请注明出处:http://www.yc00.com/xitong/1715218863a2584210.html
评论列表(0条)