【问题标题】:How to convert a REAL (32-bit float) to an 8-bit byte array in IEEE 754 representation?如何在 IEEE 754 表示中将 REAL(32 位浮点数)转换为 8 位字节数组?
【发布时间】:2018-05-18 03:20:02
【问题描述】:

我正在使用罗克韦尔自动化互联组件研讨会 (CCW)。

我需要将 REAL 类型转换为要通过 RS-232/ASCII 发送的字节数组。如何实现?

【问题讨论】:

    标签: plc structured-text


    【解决方案1】:

    最简单的方法是使用 COP 指令。

    将源元素中的二进制数据复制到目标 元素。源元素保持不变。

    COP_1(Enable:=TRUE, Src:=3.14, SrcOffset:=0, Dest:=byte_array, DestOffset:=0, Length:=4, Swap:=FALSE);
    

    缺点是在继续之前您需要额外的代码来验证 COP 是否完成。

    【讨论】:

      【解决方案2】:

      创建一个用户定义的函数,比如 REAL_TO_754_INT(所有变量都是 DINT,除了 In_f32 和 norm_f32,它们是 REAL):

      // Ref: http://beej.us/guide/bgnet/examples/pack2.c
      
      IF In_f32 = 0.0 THEN
          // get this special case out of the way
          REAL_TO_754_INT := 0;
      
      ELSE
      
          // check sign and begin normalization
          IF In_f32 < 0.0 THEN
              sign := 1;
              norm_f32 := -In_f32;
      
          ELSE
              sign := 0;
              norm_f32 := In_f32;
      
          END_IF;
      
          // get the normalized form of f and track the exponent
          shift := 0;
          WHILE (norm_f32 >= 2.0) DO
              norm_f32 := norm_f32 / 2.0;
              shift := shift + 1;
          END_WHILE;
          WHILE (norm_f32 < 1.0) DO
              norm_f32 := norm_f32 * 2.0;
              shift := shift - 1;
          END_WHILE;
          norm_f32 := norm_f32 - 1.0;
      
          // calculate the binary form (non-float) of the significand data
          // 23 is the number of significand bits
          significand := ANY_TO_DINT(norm_f32 * ANY_TO_REAL(SHL(1, 23)) + 0.5);
      
          // get the biased exponent
          // 7 is (number of exponent bits, 8)-1
          expn := shift + (SHL(1,7) - 1); // shift + bias
      
          // return the final answer
          // 31 is (the total number of bits, 32)-1
          REAL_TO_754_INT := OR_MASK(OR_MASK(SHL(sign, 31), SHL(expn, 23)), significand);
      
      END_IF; // In_f32
      

      然后重复mask和shift来划分字节:

      as_DINT := REAL_TO_754_INT(your_REAL);
      message[1] := ANY_TO_BYTE(AND_MASK(as_DINT, 16#FF));
      message[2] := ANY_TO_BYTE(AND_MASK(SHR(as_DINT,8), 16#FF));
      message[3] := ANY_TO_BYTE(AND_MASK(SHR(as_DINT,16), 16#FF));
      message[4] := ANY_TO_BYTE(AND_MASK(SHR(as_DINT,24), 16#FF));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-29
        • 1970-01-01
        • 1970-01-01
        • 2013-02-16
        • 1970-01-01
        相关资源
        最近更新 更多