技术论坛

 【分享】关于MODBUS DOUBLE型数据读取问题(64位浮点数)

返回主题列表
作者 主题
YiMoon
至圣

经验值:11740
发帖数:1228
精华帖:36
楼主    2015-12-10 12:46:52
主题:【分享】关于MODBUS DOUBLE型数据读取问题(64位浮点数) 精华帖 

 前段时间有个项目,要读取流量计的总流量,走的MODBUS RTU通讯,200PLC,流量计是厂家指定好的。因为MODBUS做的多了,心想没什么难度,且仪表还没采购,就先把程序做好了。等仪表到了之后傻眼了,总流量是DOUBLE型的浮点数,PLC只支持32位呀。于是网上各种找,也找到了一些资料,同是也看到了很多网友也有这方面的问题,于是自已写了一段程序(用300写的,方便模拟)。

32位浮点数和64位浮点数的结构,如下图:

无标题.jpg

 

程序:

FUNCTION "LREAL2REAL_XXD" : REAL
TITLE =
VERSION : 0.1


VAR_INPUT
  IN : ARRAY  [1 .. 2 ] OF DWORD ; 
END_VAR
VAR_TEMP
  E : DWORD ; 
  MT : REAL ; 
  S : DWORD ; 
  TEMP0 : DWORD ; 
  MM : DWORD ; 
  TEMP1 : DWORD ; 
  M1 : REAL ; 
  TEMP_1 : REAL ; 
  M2 : REAL ; 
  REAL1 : REAL ; 
  REAL2 : REAL ; 
  REAL3 : REAL ; 
  M_REAL : REAL ; 
END_VAR
BEGIN
NETWORK
TITLE =

      L     0;
      T     #M1;

NETWORK
TITLE =

//************判断第63位S,为1:负数,为0:正数****************

      L     #IN[1];                  // 取MODBUS传过来的第1,2个字
      SRD   31;                     //取符号位
      L     1;
      ==D   ;
      JCN   _001;
      L     DW#16#80000000;    //为1就设定63位为1
      T     #S;
      JU    _002;

_001: L     0;                        //为0 就设定为0
      T     #S;
_002: NOP   0;

//*************************************************************************


NETWORK
TITLE =

//*********************************取阶码E,共11位*****************************

      L     #IN[1];
      SRD   20;                                   //去掉尾数位,共20位
      L     DW#16#7FF;                      //去掉符号位
      AD    ;
      L     DW#16#FFFFFC01;           //减去1023(此数为-1023)
      +D    ;
      T     #E;

//*******************************************计算第1,2个字的尾数******************************
      L     #IN[1];
      L     DW#16#FFFFF;       //取第1,2个字的共20位的尾数

      AD    ;
      T     #MM;

//********************** 20位,逐个移位进行计算**************************

      L     20;                        
LOOP: T     #TEMP0;
      L     1;
      L     #MM;
      SRD   ;
      T     #MM;
      JZ    _003;

      L     2.000000e+000;           //1/2^#MM
      LN    ;
      L     #TEMP0;
      DTR   ;
      *R    ;
      EXP   ;

      L     1.000000e+000;
      TAK   ;
      /R    ;
      T     #M_REAL;
      L     #M1;                                  //逐位移出计算并累加
      +R    ;
      T     #M1;

_003: NOP   0;


      L     #TEMP0;
      LOOP  LOOP;

//************************************************第3,4个字的尾数逐位移出计算,共32位**********************
      L     #IN[2];
      T     #MM;
      L     32;
LOP:  T     #TEMP0;
      L     20;
      +D    ;
      T     #TEMP1;
      L     1;
      L     #MM;
      SRD   ;
      T     #MM;
      JZ    _004;
      L     2.000000e+000;
      LN    ;
      L     #TEMP1;
      DTR   ;
      *R    ;
      EXP   ;
      L     1.000000e+000;
      TAK   ;
      /R    ;
      T     #M_REAL;
      L     #M2;
      +R    ;
      T     #M2;
_004: NOP   0;


      L     #TEMP0;
      LOOP  LOP;
//***************************************
      L     #M1;
      L     #M2;
      +R    ;
      T     #MT;

NETWORK
TITLE =

//********************F=(-1)^S*2^(E[10进制]-127)*(1+M[尾数])*************************

      L     2.000000e+000;
      LN    ;
      L     #E;
      DTR   ;
      *R    ;
      EXP   ;

      T     #REAL2;

      L     1.000000e+000;
      L     #MT;
      +R    ;
      T     #REAL3;


      L     #REAL2;
      L     #REAL3;
      *R    ;
      L     #S;
      OD    ;
      T     #RET_VAL;

END_FUNCTION

 

Keep calm and carry on!!!
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。