包含一个接口(例如“ICmpEventCallback”)


要求

  • 创建一个“标准项目”并选择 CODESYS ControlWin V3 作为设备。
  • 通过网络扫描连接目标系统

图1

  • 打开库管理器并添加以下库: CmpApp CmpEventMgr StringUtils SysTypes2 Interfaces

图2

创建事件处理程序

  • 创建一个名为 FB_EventHandler 的新 FB 并实现接口 CmpEventMgr.ICmpEventCallback。EventCallback 方法是使用FB自动创建的:

图3

图4

  • 将以下变量添加到 FB_EventHandler:

声明

FUNCTION_BLOCK FB_EventHandler IMPLEMENTS ICmpEventCallback
VAR_OUTPUT
   udiStartDone     : UDINT;
   udiStopDone      : UDINT;
   udiLogin         : UDINT;
END_VAR
VAR
   hEventStart      : SysTypes.RTS_IEC_HANDLE;
   hEventStop       : SysTypes.RTS_IEC_HANDLE;
   hInterfaceStart  : SysTypes.RTS_IEC_HANDLE;
   hInterfaceStop   : SysTypes.RTS_IEC_HANDLE;
   iecResult        : SysTypes.RTS_IEC_RESULT;
   itfEvtCallback   : CmpEventMgr.ICmpEventCallback;
   hEventLogin      : SysTypes.RTS_IEC_HANDLE;
   hInterfaceLogin  : SysTypes.RTS_IEC_HANDLE;
   _dwStopReason    : DWORD;
  _sAppName         : STRING;
END_VAR

  • 修改方法 EventCallback,如下所示:

声明

METHOD EventCallback : CmpEventMgr.RTS_IEC_RESULT
VAR_INPUT
    (*Pointer to the event parameters, see Struct EventParam*)
    pEventParam : POINTER TO CmpEventMgr.EventParam;
END_VAR
VAR
    pStartParam : POINTER TO EVTPARAM_CmpApp;
    pStopParam  : POINTER TO EVTPARAM_CmpAppStop;
    pLoginParam : POINTER TO EVTPARAM_CmpAppComm;
END_VAR

实现

CASE pEventParam^.EventId OF
    CmpApp.EventIDs.EVT_StartDone:
        pStartParam := pEventParam^.pParameter;
        IF pStartParam <> 0 THEN
            StrCpyA(ADR(_sAppName), SIZEOF(_sAppName), ADR(pStartParam^.pApp^.szName));
        END_IF
        udiStartDone := udiStartDone + 1;
    CmpApp.EventIDs.EVT_PrepareStop:
        pStopParam := pEventParam^.pParameter;    
        IF pStopParam <> 0 THEN
            _dwStopReason := pStopParam^.ulStopReason;
        END_IF
        udiStopDone := udiStopDone + 1;
    CmpApp.EventIDs.EVT_Login:
        pLoginParam := pEventParam^.pParameter;
        udiLogin := udiLogin + 1;             
END_CASE

  • 将方法 FB_Init 添加到 FB_EventHandler 并按如下方式修改代码:

声明

METHOD FB_Init: BOOL
VAR_INPUT
   bInitRetains: BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold)
   bInCopyCode : BOOL; // TRUE: the instance will be copied to the copy code afterward (online change)
END_VAR

实现

itfEvtCallback := This^;
hEventStart := EventOpen(CmpApp.EventIds.EVT_StartDone, CmpApp.EventIds.CMPID_CmpApp, iecResult);
hEventStop := EventOpen(CmpApp.EventIds.EVT_PrepareStop, CmpApp.EventIds.CMPID_CmpApp, iecResult);
hEventLogin := EventOpen(CmpApp.EventIds.EVT_Login , CmpApp.EventIds.CMPID_CmpApp, iecResult);

hInterfaceStart := EventRegisterCallback(hEventStart, itfEvtCallback, iecResult); 
hInterfaceStop := EventRegisterCallback(hEventStop, itfEvtCallback, iecResult);
hInterfaceLogin := EventRegisterCallback(hEventLogin, itfEvtCallback, iecResult);

  • 将 FB_Exit 方法添加到 FB_EventHandler 并按如下所示修改代码:

声明

METHOD FB_Exit: BOOL
VAR_INPUT
    bInCopyCode: BOOL;  // TRUE: the exit method is called in order to leave the instance which will be copied afterwards (online change).
END_VAR

实现

EventUnregisterCallback(hEventStart, hInterfaceStart);
EventUnregisterCallback(hEventStop, hInterfaceStop);
EventUnregisterCallback(hEventLogin, hInterfaceStop);
EventClose2(hEventStart);
EventClose2(hEventStop);
EventClose2(hEventLogin);

实例化事件处理程序并测试功能

  • 按如下修改 PLC_PRG:

声明

VAR
    udiCntStart     : UDINT;
    udiCntStop      : UDINT;
    udiCntLogin     : UDINT;
    fbEventHandler  : FB_EventHandler;
END_VAR

实现

fbEventHandler(udiStartDone => udiCntStart, udiStopDone => udiCntStop, udiLogin => udiCntLogin);

  • 将项目下载到控制器并启动它。 登录/注销并启动项目时,计数器将递增。

图5