4

我有一个通过 Profibus DP 与 PLC 通信的硬件,它向我发送 4 个十六进制字节的数据,即“44 79 FF FF”,并且在 PLC 程序中,我为此输入数据声明了一个 BYTE 数组。问题是在 PLC 中,我在 BYTE 数组中收到的数据是“66 121 255 255”,这是十六进制的十进制值,但我的目标是将该值转换为 REAL,当我这样做时,我不是得到我期望的价值。

我创建了一个 DWORD( 4bytesData),我将所有 BYTES 插入其中。所以在我将 4 个字节插入4bytesData字节之前是:in1 = 68, in2 = 121, in3 = 255&in4 = 255

4bytesData := (SHL(SHL(SHL(BYTE_TO_DWORD(in1), 8) OR BYTE_TO_DWORD(in2), 8) OR     BYTE_TO_DWORD(in3), 8) OR in4);

realValue := DWORD_TO_REAL(4bytesData);

其中 in1、in2、in3 和 in4 是字节 0-3。

我得到的价值是;4bytesData= 1148846079 & realValue= 1.148846e+009

我期望从中获得的价值realValue是= 9.9999993896484375E2

如果我使用这个网站( IEEE754 Analyzer/Converter)并转换十六进制值(4479FFFF),我得到我想要的值,如果我插入十进制值(1148846079),我得到的值与我在可编程逻辑控制器。

我希望你能理解我的问题,非常感谢提前。

4

5 回答 5

4

你已经想通了,似乎你只是没有意识到。转换DWORD_TO_REAL采用存储在其中的整数(十六进制)值4bytesData并将其转换为 IEEE754 REAL 格式。

这不是你想要做的。 4479FFFF已经采用 IEEE754 REAL 格式 - 您正在获取该值,将 REAL 解释为 DWORD,然后将 DWORD 值转换为 REAL。简短的回答是您不需要转换 -4bytesData格式已经正确。

编辑

跟进评论:

在此处输入图像描述

这里 FunctionBlock2 声明了 rIn(REAL)、rOut(REAL) 和 sets rOut:=rIn;。这绕过了 ST 的强制类型转换。存储在此处的数据没有任何变化D2000- 它是相同的二进制数据。顶部功能块将其存储到内存中,底部功能块从内存中读取它。唯一的区别是顶部梯级将其解释为 DWORD(用于显示目的),而底部梯级将其解释为 REAL。

编辑

我一直在阅读 Beckhoff 手册。看来您可能还有其他选择。尝试在同一内存位置声明 DWORD 和 REAL。如果不是,也许指针会让你这样做(不确定类型限制是否也适用于 Beckhoff 的指针?)

于 2013-04-19T13:54:15.690 回答
1

如果有人感兴趣,我制作了这个在 Beckhoff PLC 上工作的函数,用于将 4 字节数组转换为实数:

(*声明*)

FUNCTION BYTE_TO_REAL : REAL
VAR_INPUT
abValueIn : ARRAY[0..3] OF BYTE;
END_VAR
VAR
pByteIn1, pByteIn2, pByteIn3, pByteIn4: POINTER TO BYTE;
rValueOut : REAL;
END_VAR

(*实施*)

pByteIn1 := ADR(rValueOut);
pByteIn2 := ADR(rValueOut) + SIZEOF(BYTE);
pByteIn3 := ADR(rValueOut) + 2 * SIZEOF(BYTE);
pByteIn4 := ADR(rValueOut) + 3 * SIZEOF(BYTE);

(*watch out, small endians needed here*)
pByteIn1^ := abValueIn[3]; 
pByteIn2^ := abValueIn[2]; 
pByteIn3^ := abValueIn[1]; 
pByteIn4^ := abValueIn[0]; 

BYTE_TO_REAL := rValueOut;

正如我发现的那样,REAL 存储在 4 个字节上,最后是强字节。我的意思是,与IEEE-754 转换器相比,字节的排序方向相反,所以我必须在代码中反转它。

我没有抓住十进制 - 十六进制的原始问题。在 twincat IDE 中,值在调试中以十进制显示,但在内部,这应该没有任何区别

于 2018-11-19T12:30:12.377 回答
0

您的字节顺序可能是错误的,并且您的例程期望相反的字节序。尝试 FFFF7944 而不是 4479FFFF 并查看是否按预期获得 9.9999993896484375E2。此外, 1148846079 是 00F4884E 作为 IEEE754 (如果需要更改字节顺序),因此您的感知中可能有不止一个错误。

于 2013-04-19T11:17:05.840 回答
0

小心嵌套所有 SHL。在 V2.3 中,您只能深入 4 层。我在不同的控制器(可能是目标的编译器)上发现你可以通过嵌套得到错误的评估。最好让他们保持自己的路线。将 4 行代码放入函数 FUNCTION BYTES_TO_DWROD : DWORD 中,您就可以一遍又一遍地重用您的转换。

于 2015-11-14T01:11:22.607 回答
0

使用指针将值从 DWORD 移动到 REAL。它似乎阻止了转换。

于 2016-06-02T14:48:13.787 回答