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:TheFIXdatabasehandlesupto32-bitvalues.Consequently,64-bitvaluesareconvertedto32-bitbeforebeingstoredintheprocessdatabase.意思是数据库只支持32位,64位的数据进数据库前转换成32位。似乎没法了!联想到Float和WFloat是高低字位置交换了,而Modscan32读出的累积值使用的是WFloat64,高低字交换了,这个问题实际上是数据存放顺序造成的。那么,只要知道原始数据的存放方式,好像还可以通过脚本处理这一问题。Modscan可以以各种方式显示数据,改变数据显示方式,很容易找到原始数据的存储方式。二、浮点数的表示32位浮点数的标准格式IEEE754313023220SEM其值为:x=(-1)S×(1.M)(E-127)64位浮点数的标准格式IEEE754636252510SEM其值为:x=(-1)S×(1.M)(E-1023)其中:S--尾数符号,0正1负;E--阶码,采用移码表示(移码可表示阶码符号)。M--尾数,纯小数,小数点放在尾数域的最前面,采用原码表示。每位的权值为2(位号-52),第51位权值是2-1=0.5,第50位权值是2-2=0.25,第49位权值是2-3=0.125,......,依此类推。三、实际数据分析流量计的累积值存储在30009-300124个寄存器中,各自值分别为:30009----16687......63-48位30010----39434......47-32位30011----23508......31-16位30012----19541......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=HHAnd32768)/32768阶码:ex=(HHAnd32752)/16尾数:ma=(((LL/65536+LH)/65536)+HL)/65536+HHAnd15)/16处理脚本如下:DimF(4)AsLongDimS,EAsIntegerDimM,MFAsDoubleDimMT(10)AsDouble'读入双精度浮点数的4个字,不管原始数据咋排列,在这里按最高字、次高字、次低字、最低字的顺序排列F(0)=16687'readvalue(fix32.Mynd1.f64.f_0)F(1)=39434'readvalue(fix32.Mynd1.f64.f_1)F(2)=23508'readvalue(fix32.Mynd1.f64.f_2)F(3)=19541'readvalue(fix32.Mynd1.f64.f_3)S=(F(0)And32768)/32768E=(F(0)And32752)/16MT(1)=(F(0)And15)/16MT(2)=F(1)/16/65535MT(3)=F(2)/16/65535/65535MT(4)=F(3)/16/65535/65535/65535MT(0)=MT(1)+MT(2)+MT(3)+MT(4)M=MT(0)+1MF=((-1)^S)*(2^(E-1023))*Muser.f64.CurrentValue=MFFix32.Fix.f64.f_cv=MFFix32.Fix.aisim.f_cv=MF执行结果如上;使用SIM驱动器的Fix32.fix.aisim和使用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日