无法将“UDINT”类型转换为“POINTER TO BOOL”类型 Beckhoff 中出现错误。 FB 曾在 Codesys (IFM) 工作多年

问题描述 投票:0回答:1

我正在尝试在 Beckhoff 中重用我在 Codesys 中使用多年的 FB。 Beckhoff 基于 Codesys,因此我预计不会出现任何问题。我认为该错误与 Codesys 中可能的类型转换有关,但在 Beckhoff 中则不然。错误:无法将类型“UDINT”转换为类型“POINTER TO BOOL”。

在我的代码下面可以找到。该 FB 已在多个项目中使用 IFM 的 PLC 工作了 5 年以上。


FUNCTION_BLOCK FC_AlarmsHandler
VAR_INPUT
    LI_bIN: BOOL;
    /// Reset Alarms bits - only Alarms that are acknowledged 
    LI_bReset: BOOL;
    /// Acknowledge all active Alarms bits at once 
    LI_bAckAll: BOOL;
    /// Hold time of new alarm 
    LI_rHoldTimeNewAlarms: REAL;
    /// Base address of Alarms group struct 
    LI_adrAlarmsGroup: DWORD;
    /// Number of Alarms group elements 
    LI_sizeofAlarmsGroup: UINT;
    /// Base address of Alarms struct 
    LI_adrAlarms: DWORD;
    /// Base address of Alarms old array of bool 
    LI_adrAlarmsOld: DWORD;
    /// Base address of Alarms hold array of bool 
    LI_adrAlarmsHold: DWORD;
    /// Base address of Alarms acknowledge array of bool 
    LI_adrAlarmsAck: DWORD;
    LI_adrAlarmsText: POINTER TO STRING(64);
END_VAR
VAR_OUTPUT
    LQ_bOUT: BOOL;
    /// New Alarm -> this output is one cycle high 
    LQ_bNewAlarm: BOOL;
    /// When an alarm is active, this output is high 
    LQ_bAlarmActive: BOOL;
    /// Alarm gone -> this output is one cycle high 
    LQ_bAlarmGone: BOOL;
END_VAR
VAR
    LT_bInit: BOOL;
    /// offset for group address 
    LT_adrOffsetGroup: DWORD;
    LT_iNumberOfAlarmGroupElements: UINT;
    /// Number of lines for alarm visualization table in Hmi 
    LT_iNumberOfHmiLines: INT;
    /// Number of lines for alarm history visualization table in Hmi 
    LT_iNumberOfHmiHistoryLines: INT;
    LT_ptAlarms: POINTER TO BOOL;
    LT_ptAlarmsOld: POINTER TO BOOL;
    LT_ptAlarmsHold: POINTER TO BOOL;
    LT_ptAlarmsAck: POINTER TO BOOL;
    LT_ptAlarmsText: POINTER TO STRING(64);
    LT_iCounterAlarmsElements: INT;
    /// Timer for holding new alarm 
    fbTofNewAlarm: TOF;
END_VAR
LQ_bOUT:=LI_bIN;
// Init 
IF LT_bInit = FALSE THEN
    LT_adrOffsetGroup := LI_adrAlarmsGroup - LI_adrAlarms;
    LT_iNumberOfAlarmGroupElements := LI_sizeofAlarmsGroup / SIZEOF(LT_ptAlarms^); 
    // Alarm array for HMI
    LT_iNumberOfHmiLines := GDI_Alarms.iNumberOfHmiLines;
    // Alarm history array for HMI
    LT_iNumberOfHmiHistoryLines := GDI_Alarms.iNumberOfHmiHistoryLines;
    LT_bInit := TRUE;
END_IF

(***************************************************************************)
(* Alarm handling *)
(***************************************************************************)

[HERE I AM HAVING MY PROBLEMS] 
// Init new scan cycle
LT_ptAlarms := LI_adrAlarms + (LT_adrOffsetGroup * SIZEOF(LT_ptAlarms^));
LT_ptAlarmsText := LI_adrAlarmsText + (LT_adrOffsetGroup * SIZEOF(LT_ptAlarmsText^));
LT_ptAlarmsOld := LI_adrAlarmsOld + (LT_adrOffsetGroup * SIZEOF(LT_ptAlarmsOld^));
LT_ptAlarmsHold := LI_adrAlarmsHold + (LT_adrOffsetGroup * SIZEOF(LT_ptAlarmsHold^));
LT_ptAlarmsAck := LI_adrAlarmsAck + (LT_adrOffsetGroup * SIZEOF(LT_ptAlarmsAck^));


LQ_bNewAlarm:= FALSE;
LQ_bAlarmActive := FALSE;
LQ_bAlarmGone := FALSE;

FOR LT_iCounterAlarmsElements := 1 TO LT_iNumberOfAlarmGroupElements DO // Scan all data of group
    // Check for new alarms 
    IF LT_ptAlarms^ AND NOT LT_ptAlarmsOld^ THEN
        LQ_bNewAlarm:= TRUE;
    END_IF

    // Reset current alarms 
    IF LI_bReset AND LT_ptAlarmsAck^ AND NOT LT_ptAlarms^ THEN
        LT_ptAlarms^ := FALSE;
    ELSE
        LT_ptAlarms^ := LT_ptAlarms^ OR LT_ptAlarmsOld^; (* keep alarms true *)
    END_IF

    // Hold new alarms 
    IF fbTofNewAlarm.Q = TRUE THEN
        LT_ptAlarmsHold^ := LT_ptAlarms^ OR LT_ptAlarmsHold^;
    ELSE
        LT_ptAlarmsHold^ := LT_ptAlarms^;
    END_IF

    // Acknowlegde current alarms
    IF LI_bAckAll THEN
        LT_ptAlarmsAck^ := LT_ptAlarms^;
    END_IF

    // check if alarm is gone 
    IF NOT LT_ptAlarms^ AND LT_ptAlarmsOld^ THEN
        LQ_bAlarmGone := TRUE;
    END_IF
    
    // Alarms active
    IF LT_ptAlarms^ THEN
        LQ_bAlarmActive:= TRUE;
    END_IF

    // Save old value 
    LT_ptAlarmsOld^ := LT_ptAlarms^;

    // Next element 
    LT_ptAlarms := LT_ptAlarms + SIZEOF(LT_ptAlarms^); // Pointer to next element
    LT_ptAlarmsText := LT_ptAlarmsText + SIZEOF(LT_ptAlarmsText^); // Pointer to next element
    LT_ptAlarmsOld := LT_ptAlarmsOld + SIZEOF(LT_ptAlarmsOld^); // Pointer to next element
    LT_ptAlarmsHold := LT_ptAlarmsHold + SIZEOF(LT_ptAlarmsHold^); // Pointer to next element
    LT_ptAlarmsAck := LT_ptAlarmsAck + SIZEOF(LT_ptAlarmsAck^); // Pointer to next element

END_FOR
fbTofNewAlarm(in:= LQ_bNewAlarm, PT:= REAL_TO_TIME(LI_rHoldTimeNewAlarms), Q=> ,    ET=> );

我已经尝试添加转换 UDINT_TOPBOOL、UDINT_TODWORD (因为标准指针数据类型),但这不起作用。

pointers types plc twincat codesys
1个回答
0
投票

我强烈怀疑您这些年来一直使用 32 位版本的 CODESYS,现在正在转向 64 位 Beckhoff PLC。

如果是这样,您的问题不是从 CODESYS 迁移到 TwinCAT 造成的,而是从 32 位迁移到 64 位造成的。亲自尝试一下:返回 CODESYS,然后选择任何 64 位运行时。编译时会出现与 TwinCAT 中相同的错误。

  • 您可能不应该使用 DWORD 变量来传递地址。使用“指针”。更好的是,使用“参考”。这将在不同的 CPU 架构上编译和工作。

  • 您似乎正在使用偏移量计算在单个结构中找到的许多变量的地址,而不是使用指向该结构的单个指针(或引用)并使用“。”访问其字段。我还没有完全分析你的代码,但在我看来,它会大大简化它,因为你将摆脱所有指针计算并将这项工作卸载给编译器。

© www.soinside.com 2019 - 2024. All rights reserved.