首页 > 解决方案 > PLC编程:转换为相同大小的数据类型并返回更改实际值

问题描述

一个功能块给了我一些数据类型 REAL。Real 必须转换为 DWORD。在使用的平台上,数据类型具有以下大小:

因此,我认为如果仅在这两种数据类型之间传输位表示,则该值不会改变或降低精度。我想做的是以下几点:

myReal : REAL;
myDWord : DWORD;
myResultReal : REAL;

myReal := 0.819;

myDWord := REAL_TO_DWORD(myReal);
myResultReal := DWORD_TO_REAL(myDWord);

// myResultReal has value: 1
// Also when I check the bit string of the myDWord it differs from the actual
// bit string of myReal. Immediately after the first conversion.

整个问题只是编程语言的规则。由于两种数据类型具有相同的内存大小,因此似乎完全没有必要进行转换。转换的实际原因只是因为我需要稍后将我的数字传递给代码,它只接受 DWORD 数据类型。然后它使用 DWORD 来获得一个 REAL,但此时该值受到了不希望的影响。

标签: typestype-conversionimplicit-conversionplcst

解决方案


有两种选择。更高级的是pboedker建议的:UNION 数据类型。

例子:

TYPE U_TestUnion :
UNION
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_UNION
END_TYPE   

VAR
    TestUnion   : U_TestUnion;
END_VAR

 TestUnion.Value_REAL := 0.819;
 //TestUnion.Value_DWORD is now 1062316540 (=16#3F51A9FC)

 TestUnion.Value_DWORD := 10; 
 //TestUnion.Value_REAL is now 1.401298E-44 

 TestUnion.Value_DWORD := 1062316540; 
 //TestUnion.Value_REAL is now 0.819 

另一个是使用 MEMCPY 函数,它将值从内存复制到其他位置。该函数在不同的系统中可以命名略有不同。通过这样做,您可以将内容从 REAL 值的位置复制到 DWORD 的地址并向后复制。

在 REAL->DWORD 方向,应该不用担心。但是当从 DWORD 复制到 REAL 时,如果数据有可能在任何地方被修改,则可能会出现一些问题。该值可能是NaNInfinity,这可能会导致 PLC 崩溃。这意味着 REAL 不是格式正确的十进制数。

VAR
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_VAR

Value_REAL := 0.819;
MEMCPY(destAddr:=ADR(Value_DWORD), srcAddr:=ADR(Value_REAL), n:=SIZEOF(Value_REAL));
 //Value_DWORD is now 1062316540 (=16#3F51A9FC)

Value_DWORD := 10; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 1.401298E-44 

Value_DWORD := 1062316540; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 0.819 

推荐阅读