BOOL 和 WORD 的联合位映射

union bit mapping of BOOL and WORD

我试图在单个字中映射一些位,但我看到编译时 bool 的大小等于一个字节。当我看到执行中的代码时,每个 BOOL 都是 8 位大小。如何在 struct 或 union 中指定位域? 那是我的代码:

TYPE FAULT_CODE:
STRUCT 
fault1,falut2,fault3: BOOL;

END_STRUCT
END_TYPE

TYPE U_fault :
UNION
    faultCode: FAULT_CODE;
    in: WORD;
END_UNION
END_TYPE

回答

您要查找的 ST 数据类型是 BIT

  • BOOL:8 位
  • 位:1位

You can only use the data type BIT for individual variables within structures or function blocks. The possible values are TRUE (1) and FALSE (0).

A BIT element requires 1 bit of memory space, and you can use it to address individual bits of a structure or function block using its name. BIT elements, which are declared sequentially, are consolidated to bytes. This allows you to optimize memory usage compared to BOOL types, which each occupy at least 8 bits. However, bit access takes significantly longer. Therefore, you should only use the data type BIT if you want to define the data in a specified format.


示例

TYPE st_Flags :
STRUCT
    Bit1  : BIT;
    Bit2  : BIT;
    Bit3  : BIT;
    Bit4  : BIT;
    Bit5  : BIT;
    Bit6  : BIT;
    Bit7  : BIT;
    Bit8  : BIT;
END_STRUCT
END_TYPE
TYPE u_Error :
UNION
    _Byte   : BYTE;
    _Flag   : st_Flags;
END_UNION
END_TYPE

您应该避免使用 BIT 数据类型,因为 Beckhoff 基于 PC 的控制没有小型嵌入式系统或较旧的 PLC 系统所具有的内存限制。

在 Beckhoff 文档中指出,BIT 访问操作比正常的 BOOL 访问操作花费的时间更长。

CPU-时间是需要考虑的更重要的资源,因为更快的 CPU 比 RAM 棒贵得多(并且使用 4gb 的 RAM,您可以分配很多布尔值)。

就是说,如果您想评估一个 WORD 是因为您想从中提取故障代码,请使用 CASE OF 语句。

每个 CASE 都是一种 ERROR 类型,也可以声明为 ENUM 类型。

枚举示例:

TYPE E_Error :
(
    eNO_ERROR := 0,
    eGENERAL_ERROR,
    eMOTION_ERROR,
    eSAFETY_ERROR
);
END_TYPE

CASE OF 语句示例:

CASE wError OF
    eNO_ERROR:
        ;
    eGENERAL_ERROR:
        ;
    eMOTION_ERROR:
        ;
    eSAFETY_ERROR:
        ;   
END_CASE

要添加到 Steves 的答案中,您还可以使用 Bit Access to Variables 放弃创建自定义数据类型的需要!

如果您的变量是整数类型(SINT、INT、DINT、USINT、UINT、UDINT、BYTE、WORD、DWORD),那么您可以访问它的各个位像这样:

VAR
    myWord: WORD;
END_VAR

myWord.0 := FALSE;
myWord.1 := TRUE;
myWord.2 := FALSE;
myWord.3 := TRUE;
myWord.4 := FALSE;
myWord.5 := TRUE;
// And so on

正如上面提到的 Filippo Boido,BOOL 本质上要快得多,因此除非你内存不足,或者需要通过总线在 WORD 中传递数据,使用首选 BOOL 数组。

参考史蒂夫的例子​​,我个人也使用这种更紧凑的形式,通过扩展位结构与联合

TYPE u_Error EXTENDS st_Flags :
UNION
    _Byte   : BYTE;
END_UNION
END_TYPE

所以在输出中有这个:

VAR
    uError : u_Error ;
END_VAR

uError._Byte;
uError.Bit1;
uError.Bit2;
uError.Bit3;
...

而不是

uError._Byte;
uError._Flag.Bit1;
uError._Flag.Bit2;
uError._Flag.Bit3;
...