西门子SCL编程:SCL编写的DCS电机块

本文介绍了一种使用S7-300 PLC实现的电机控制功能块,该功能块能够通过WinCC界面进行操作,并支持多种运行模式如手动、自动和模拟。此外,还详细介绍了故障监测及反馈机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

N年之前,用S7-300做一个小型DCS项目,选用wincc为人机界面。项目中电机、泵、风机类比较多,于是下功夫研究编写这个电机块。功能确实强大,在wincc中自动生成图标,拽出来直接用就可。

FUNCTION_BLOCK MOTOR1DIR_300
NAME:MOTOR1DIR
FAMILY:S7-300 BLOCK
AUTHOR:SDZYG2000
//VERSION:'1.01'
//FB620

// Typical-Attribute
{
  S7_tasklist:='OB100';
  S7_m_c:='true';
  S7_blockview:='big'
}

// Parameterattribute
// S7_visible       visible/unvisible   (default='true')
// S7_m_c           WinCC - Tag         (default='false')
// S7_dynamic       testmode            (default='false')
VAR_INPUT
    LOCK        {S7_dynamic:='true'} : BOOL := FALSE; // Interlock
    ERR_EXTERN  {S7_dynamic:='true'} : BOOL := FALSE; // External Error
    LIOP_SEL    {S7_dynamic:='true'} : BOOL := FALSE; // 0=Operator 1=Linking
    L_AUT       {S7_dynamic:='true'} : BOOL := FALSE; // 0=Manual 1=Automatic
    L_REMOTE    {S7_dynamic:='true'} : BOOL := FALSE; // 0=Lokal 1=Remote
    L_SIM       {S7_dynamic:='true'} : BOOL := FALSE; // 0=Normal 1=Simulation
    L_RESET     {S7_dynamic:='true'} : BOOL := FALSE; // 1=Reset Error Peripherie
    AUT_ON      {S7_dynamic:='true'} : BOOL := FALSE; // 1=CMD ON Automatic
    MAN_ON      {S7_dynamic:='true'} : BOOL := FALSE; // 1=CMD ON Manual
    SIM_ON      {S7_dynamic:='true'} : BOOL := FALSE; // 1=CMD ON Simulation
    FB_ON       {S7_dynamic:='true'} : BOOL := FALSE; // Feedback Motor
    L_MON       {S7_dynamic:='true'} : BOOL := TRUE;  // 1=Monitoring ON
    MON_T       {S7_dynamic:='true'; S7_m_c := 'true'} : REAL := 10.0; // Monitoring Time
    MPS         {S7_dynamic:='true'} : BOOL := FALSE; // 1=Motor Protecting Switch ON
    L_FLOW_MON  {S7_dynamic:='true'} : BOOL := FALSE; // 1=Monitoring Flow
    FLOW        {S7_dynamic:='true'} : REAL := 0.0;   // Current Flow
    FLOW_LL     {S7_dynamic:='true'} : REAL := 5.0;   // Low Level Flow
    FLOW_MT     {S7_dynamic:='true'; S7_m_c := 'true'} : REAL := 10.0;   // Monitoring Time Flow

    SAMPLE_T    {S7_sampletime:='true'} : REAL := 0.0; // Sample Time
END_VAR

VAR_IN_OUT
    OP_dwCmd    {S7_dynamic := 'true'; S7_m_c := 'true'} : DWORD :=0;   // control word wincc
END_VAR

VAR_OUTPUT
    QdwState    {S7_dynamic:='true'; S7_m_c:='true'}: DWORD:=0;     // status wincc
    QabyState AT QdwState : ARRAY [0..3] OF BYTE;                   // look at state byte-wise
    
    QwState     {S7_dynamic:='true'}: WORD:= 0; //0=off, 1=starting, 2=on, 3=stopping
    
    QSTOPPING   {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Stopping
    QSTOP       {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Stop
    QSTARTING   {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Starting
    QRUN        {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Run
    
    QCMD_ON     {S7_dynamic:='true'} : BOOL := FALSE;     // 0=Stop 1=Start
   
    QMON        {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Monitoring Feedback
    QMON_ERR    {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Monitoring Error
    QMON_T      {S7_dynamic:='true'; S7_m_c := 'true'} : REAL := 0.0; // Current Monitoring Time Feedback
    QFLOW_MON   {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Monitoring Flow
    QFLOW_MT    {S7_dynamic:='true'; S7_m_c := 'true'} : REAL := 0.0; // Current Monitoring Time Flow
    QFLOW_ERR   {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Error Flow
    
    QMPS        {S7_dynamic:='true'} : BOOL := FALSE;     // 1=Motor Protecting Switch
    QERR        {S7_dynamic:='true'} : BOOL := FALSE;     // 1=ERROR

    QMAN_AUT   {S7_dynamic:='true'} : BOOL := FALSE;     // 0=Hand 1=Automatic
    QREMOTE    {S7_dynamic:='true'} : BOOL := FALSE;     // 0=Local 1=Remote
    QSIM       {S7_dynamic:='true'} : BOOL := FALSE;     // Simulaition is active
    QLOCK      {S7_dynamic:='true'} : BOOL := FALSE;     // Interlock is active
    QERR_EXT   {S7_dynamic:='true'} : BOOL := FALSE;     // External ERROR
    
    //Alarm
    QwAlarm    {S7_dynamic:='true'; S7_m_c := 'true'} : WORD := 16#0;   // Bit Alarm Procedure
    QabyAlarm AT QwAlarm : ARRAY [0..1] OF BYTE;         // look at QwAlarm byte-wise
END_VAR

VAR
    OPdwCmdHMI : DWORD := 16#0;                       // Operator Commands in HMI format
    OPabyCmdHMI AT OPdwCmdHMI : ARRAY [0..3] OF BYTE; // look at HMI command byte-wise
    OPdwCmdPLC : DWORD := 16#0;                       // Operator Commands in PLC format
    OPabyCmdPLC AT OPdwCmdPLC : ARRAY [0..3] OF BYTE; // look at plc command byte-wise
    OPabCmdPLC AT OPdwCmdPLC : ARRAY [0..31] OF BOOL; // look at plc command bit-wise
    
    QdwStatePLC : DWORD := 16#0;                        // State word in PLC format
    QabyStatePLC AT QdwStatePLC : ARRAY [0..3] OF BYTE; // look at state byte-wise
    QabStatePLC AT QdwStatePLC : ARRAY [0..31] OF BOOL; // look at state bit-wise
    
    QwAlarmPLC : WORD := 16#0;                          // Alarm Tag PLC Format
    QabyAlarmPLC AT QwAlarmPLC : ARRAY [0..1] OF BYTE;  // look at Alarm byte-wise
    QabAlarmPLC AT QwAlarmPLC : ARRAY [0..15] OF BOOL;  // look at Alarm bit-wise
    
    // TAGS for Simulation
    FB_SIM   : BOOL := FALSE;
    SIM_T    : REAL := 5.0;
    QCMD_SIM : BOOL := FALSE;
    
    // TAGS for Operation
    OP_RESET : BOOL := FALSE;
    
    // TAGS for Edge detect
    L_RESET_OLD : BOOL := FALSE;
    AUT_ON_OLD : BOOL := FALSE;
    MAN_ON_OLD : BOOL := FALSE;
    QSTARTING_OLD : BOOL := FALSE;
    QSTOPPING_OLD : BOOL := FALSE;
    
END_VAR

VAR_TEMP
TOP_SI: STRUCT
      EV_CLASS  : BYTE;
      EV_NUM    : BYTE;
      PRIORITY  : BYTE;
      NUM       : BYTE;
      TYP2_3    : BYTE;
      TYP1      : BYTE;
      ZI1       : WORD;
      ZI2_3     : DWORD;
END_STRUCT;

START_UP_SI: STRUCT
      EV_CLASS  : BYTE;
      EV_NUM    : BYTE;
      PRIORITY  : BYTE;
      NUM       : BYTE;
      TYP2_3    : BYTE;
      TYP1      : BYTE;
      ZI1       : WORD;
      ZI2_3     : DWORD;
END_STRUCT;
iRet     : INT;

END_VAR


BEGIN

// START UP =====================================================================
    iRet := SFC6 (TOP_SI:= TOP_SI, START_UP_SI:= START_UP_SI);
    IF (TOP_SI.NUM = 100) THEN
        
        QCMD_ON   := FALSE;
        QSTOP     := TRUE;
        QSTARTING := FALSE;
        QRUN      := FALSE;
        QSTOPPING := FALSE;
        QwState := 0;
        
        iRet := 0;
    END_IF;
// END STARTUP ==================================================================

// Change lowbyte to highbyte for HMI command word =====================
    OPdwCmdHMI := OP_dwCmd;
    OPabyCmdPLC[0] := OPabyCmdHMI[3];
    OPabyCmdPLC[1] := OPabyCmdHMI[2];
    OPabyCmdPLC[2] := OPabyCmdHMI[1];
    OPabyCmdPLC[3] := OPabyCmdHMI[0]; 

// ******************************************************************************
// Begin: Operation functions ***************************************************
    
// MANUAL / AUTOMATIC Operation =======================================
    IF (LIOP_SEL AND NOT L_AUT) OR (OPabCmdPLC[16] AND NOT LIOP_SEL) THEN 
        QMAN_AUT := FALSE;
    ELSIF (LIOP_SEL AND L_AUT) OR (OPabCmdPLC[17] AND NOT LIOP_SEL) THEN 
        QMAN_AUT := TRUE;
    END_IF;
    
// LOCAL / REMOTE Operation =========================================
    IF (LIOP_SEL AND NOT L_REMOTE) OR (OPabCmdPLC[18] AND NOT LIOP_SEL) THEN
        QREMOTE := FALSE;
    ELSIF (LIOP_SEL AND L_REMOTE) OR (OPabCmdPLC[19] AND NOT LIOP_SEL) THEN
        QREMOTE := TRUE;
    END_IF;
    
// SIMULATION ON / OFF ==============================================
    IF (LIOP_SEL AND NOT L_SIM) OR (OPabCmdPLC[20] AND NOT LIOP_SEL) THEN
        QSIM := FALSE;
    ELSIF (LIOP_SEL AND L_SIM) OR (OPabCmdPLC[21] AND NOT LIOP_SEL) THEN
        QSIM := TRUE;
        QCMD_ON := FALSE;
    END_IF;
    
// RESET Operation ==================================================
    IF (LIOP_SEL AND L_RESET AND NOT L_RESET_OLD) OR (OPabCmdPLC[24] AND NOT LIOP_SEL) THEN
        OP_RESET := TRUE;
    ELSE
        OP_RESET := FALSE;
    END_IF;
    
// MONITORING FEEDBACK ON / OFF =====================================
    IF (LIOP_SEL AND L_MON) OR (OPabCmdPLC[8] AND NOT LIOP_SEL) THEN
        QMON := TRUE;
    ELSIF (LIOP_SEL AND NOT L_MON) OR (OPabCmdPLC[9] AND NOT LIOP_SEL) THEN
        QMON := FALSE;
    END_IF;
    
// MONITORING FLOW ON / OFF =========================================
    IF (LIOP_SEL AND L_FLOW_MON) OR (OPabCmdPLC[10] AND NOT LIOP_SEL) THEN
        QFLOW_MON := TRUE;
    ELSIF (LIOP_SEL AND NOT L_FLOW_MON) OR (OPabCmdPLC[11] AND NOT LIOP_SEL) THEN
        QFLOW_MON := FALSE;
    END_IF;

// START / STOP Motor (AUTOMATIC)====================================
    IF (QMAN_AUT AND AUT_ON AND NOT AUT_ON_OLD AND NOT QSIM) THEN
        QCMD_ON := TRUE;
    ELSIF (QMAN_AUT AND NOT AUT_ON AND NOT QSIM) THEN
        QCMD_ON := FALSE;
    END_IF;
    
// START / STOP Motor (MANUAL)=======================================
    IF (NOT QMAN_AUT AND NOT QREMOTE AND MAN_ON AND NOT MAN_ON_OLD AND NOT QSIM) OR (OPabCmdPLC[1] AND NOT QMAN_AUT AND QREMOTE AND NOT QSIM)  THEN
        QCMD_ON := TRUE;
    ELSIF (NOT QMAN_AUT AND NOT QREMOTE AND NOT MAN_ON AND NOT QSIM) OR (OPabCmdPLC[0] AND NOT QMAN_AUT AND QREMOTE AND NOT QSIM) THEN
        QCMD_ON := FALSE;
    END_IF;

// START / STOP Motor (SIMULATION)===================================
    IF (QSIM AND NOT QREMOTE AND SIM_ON) OR (OPabCmdPLC[1] AND QREMOTE AND QSIM) THEN
        QCMD_SIM := TRUE;
    ELSIF (QSIM AND NOT QREMOTE AND NOT SIM_ON) OR (OPabCmdPLC[0] AND QREMOTE AND QSIM) THEN
        QCMD_SIM := FALSE;
    END_IF;
    
// END: Operation functions *****************************************************
// ******************************************************************************    


//=================================
//            QwState
//0 = Stop
//1 = Starting
//2 = Run
//3 = Stopping
//=================================

//--------------------------
//QwState = 0; Stop
//--------------------------
    IF NOT QSIM THEN    // *** Process Mode ***
        IF 
            (NOT QCMD_ON AND QwState=3 AND NOT QMON_ERR AND NOT FB_ON) OR
            (NOT QCMD_ON AND QwState=3 AND NOT QMON)
        THEN
            QSTOP     := TRUE;
            QSTARTING := FALSE;
            QRUN      := FALSE;
            QSTOPPING := FALSE;
            QwState := 0;
        END_IF;
    ELSE                // *** Simulation Mode ***
        IF 
            (NOT QCMD_SIM AND QwState=3 AND NOT FB_SIM) OR
            (NOT QCMD_SIM AND QwState=3 AND NOT QMON)
        THEN
            QSTOP     := TRUE;
            QSTARTING := FALSE;
            QRUN      := FALSE;
            QSTOPPING := FALSE;
            QwState := 0;
        END_IF;
    END_IF;
        
//--------------------------
//QwState = 1; Starting
//--------------------------
    IF NOT QSIM THEN    // *** Process Mode ***
        IF (QCMD_ON AND QwState = 0) THEN 
            QSTOP     := FALSE;
            QSTARTING := TRUE;
            QRUN      := FALSE;
            QSTOPPING := FALSE;
            QwState := 1;
        END_IF;
    ELSE                // *** Simulation Mode ***
        IF (QCMD_SIM AND QwState = 0) THEN 
            QSTOP     := FALSE;
            QSTARTING := TRUE;
            QRUN      := FALSE;
            QSTOPPING := FALSE;
            QwState := 1;
        END_IF;
    END_IF;
    
    
//--------------------------
//QwState = 2; RUN
//--------------------------
    IF NOT QSIM THEN        // *** Process Mode ***
        IF 
            (QCMD_ON AND QwState=1 AND NOT QMON_ERR AND FB_ON) OR
            (QCMD_ON AND QwState=1 AND NOT QMON)
        THEN
            QSTOP     := FALSE;
            QSTARTING := FALSE;
            QRUN      := TRUE;
            QSTOPPING := FALSE;
            QwState := 2;
        END_IF;
    ELSE                    // *** Simulation Mode ***
        IF  
            (QCMD_SIM AND QwState=1 AND FB_SIM) OR
            (QCMD_SIM AND QwState=1 AND NOT QMON)
        THEN
            QSTOP     := FALSE;
            QSTARTING := FALSE;
            QRUN      := TRUE;
            QSTOPPING := FALSE;
            QwState := 2;
        END_IF;
    END_IF;
        
//--------------------------
//QwState = 3; Stopping
//--------------------------
    IF NOT QSIM THEN        // *** Process Mode ***
        IF (NOT QCMD_ON AND (QwState = 1 OR QwState = 2)) THEN
            QSTOP     := FALSE;
            QSTARTING := FALSE;
            QRUN      := FALSE;
            QSTOPPING := TRUE;
            QwState := 3;
        END_IF;
    ELSE                    // *** Simulation Mode ***
        IF (NOT QCMD_SIM AND (QwState = 1 OR QwState = 2)) THEN
            QSTOP     := FALSE;
            QSTARTING := FALSE;
            QRUN      := FALSE;
            QSTOPPING := TRUE;
            QwState := 3;
        END_IF;
    END_IF;
    
    
        
// Feedback Monitoring =================================================
    IF QMON THEN
        IF (QSTARTING AND NOT QSTARTING_OLD) OR (QSTOPPING AND NOT QSTOPPING_OLD) THEN
            QMON_T := 0.0;
        END_IF;
        
        IF NOT QSIM THEN    // *** Process Mode ****
            IF (QSTARTING OR QSTOPPING) THEN
                QMON_T := QMON_T + SAMPLE_T;
                IF (QMON_T >= MON_T) THEN
                    QMON_ERR := TRUE;
                END_IF;
            ELSE
                QMON_T := 0.0;
            END_IF;
            IF (QRUN AND NOT FB_ON) OR (QSTOP AND FB_ON) THEN
                QMON_ERR := TRUE;
            END_IF;  
        ELSE               // *** Simulation Mode ***
            IF (QSTARTING) THEN
                QMON_T := QMON_T + SAMPLE_T;
                IF (QMON_T >= SIM_T) THEN
                    FB_SIM := TRUE;
                END_IF;
            ELSIF (QSTOPPING) THEN
                QMON_T := QMON_T + SAMPLE_T;
                IF (QMON_T >= SIM_T) THEN
                    FB_SIM := FALSE;
                END_IF;
            ELSE
                QMON_T := 0.0;
            END_IF;
        END_IF;
    END_IF;
// END Monitoring ======================================================

// Check Errors ========================================================
    QERR_EXT := ERR_EXTERN;
    IF LOCK AND (QSTARTING OR QRUN) THEN
        QLOCK := TRUE;
    END_IF;
    IF MPS THEN
        QMPS := TRUE;
    END_IF;
    QERR := QERR_EXT OR QMON_ERR OR QFLOW_ERR OR QLOCK OR QMPS;
    
// RESET Errors ========================================================
    IF OP_RESET THEN
        QMON_ERR  := FALSE;
        QFLOW_ERR := FALSE;
        QMPS      := FALSE;
        QLOCK     := FALSE;
    END_IF;

// If Error then Stop ==================================================        
    IF QERR THEN
        QSTOP     := TRUE;
        QSTARTING := FALSE;
        QRUN      := FALSE;
        QSTOPPING := FALSE;
        QCMD_ON   := FALSE;
        QCMD_SIM  := FALSE;
        QwState   := 0;
        QMON_T    := 0.0;
    END_IF;

// Set State for HMI ===================================================
    QabStatePLC[0]  := QSTOP;       // 1=Stop
    QabStatePLC[1]  := QSTARTING;   // 1=Starting
    QabStatePLC[2]  := QRUN;        // 1=Run
    QabStatePLC[3]  := QSTOPPING;   // 1=Stopping
    QabStatePLC[4]  := 0;
    QabStatePLC[5]  := 0;
    QabStatePLC[6]  := 0;
    QabStatePLC[7]  := 0;   
    QabStatePLC[8]  := QMON;        // 1=Feedback Monitoring ON
    QabStatePLC[9]  := QMON_ERR;    // 1=Error Feedback Monitoring
    QabStatePLC[10] := QFLOW_MON;   // 1=Flow Monitoring ON
    QabStatePLC[11] := QFLOW_ERR;   // 1=Error Flow Monitoring
    QabStatePLC[12] := QMPS;        // 1=Motor Protecting Switch
    QabStatePLC[13] := 0;
    QabStatePLC[14] := 0;
    QabStatePLC[15] := 0;
    QabStatePLC[16] := QMAN_AUT;    // 0=Manual 1=Automatic
    QabStatePLC[17] := QREMOTE;     // 0=Local 1=Remote
    QabStatePLC[18] := QSIM;        // 0=Process 1=Simulation 
    QabStatePLC[19] := 0;
    QabStatePLC[20] := 0;
    QabStatePLC[21] := 0;
    QabStatePLC[22] := 0;
    QabStatePLC[23] := 0;
    QabStatePLC[24] := QERR;        // 1=Error
    QabStatePLC[25] := QERR_EXT;    // 1=External Error
    QabStatePLC[26] := QLOCK;       // 1=Motor Locked;
    QabStatePLC[27] := LOCK;        // 1=INTERLOCK
    QabStatePLC[28] := 0;  
    QabStatePLC[29] := 0;  
    QabStatePLC[30] := 0;
    QabStatePLC[31] := 0;
    
    QabyState[0] :=QabyStatePLC[3];
    QabyState[1] :=QabyStatePLC[2];
    QabyState[2] :=QabyStatePLC[1];
    QabyState[3] :=QabyStatePLC[0];
    
// Bit alarm procedure ================================================
    QabAlarmPLC[0] :=QMON_ERR;      // Feedback Error
    QabAlarmPLC[1] :=QFLOW_ERR;     // Flowing Error
    QabAlarmPLC[2] :=QMPS;          // Motor Protect
    QabAlarmPLC[3] :=0;         
    QabAlarmPLC[4] :=QLOCK;         // Interlock Error
    QabAlarmPLC[5] :=0;
    QabAlarmPLC[6] :=QERR_EXT;      // External Error
    QabAlarmPLC[7] :=QERR;          // General Error
    QabAlarmPLC[8] :=QSTOP;         // Stop
    QabAlarmPLC[9] :=QSTARTING;     // Starting
    QabAlarmPLC[10] :=QRUN;         // Run
    QabAlarmPLC[11] :=QSTOPPING;    // Stopping
    QabAlarmPLC[12] :=LOCK;         // Interlock
    QabAlarmPLC[13] :=QREMOTE;      // Remote
    QabAlarmPLC[14] :=QMAN_AUT;     // Automatic
    QabAlarmPLC[15] :=QSIM;         // Simulation
    
    QabyAlarm[0] := QabyAlarmPLC[1];
    QabyAlarm[1] := QabyAlarmPLC[0];
    
    // Set Tags for edge detect =====================================
    L_RESET_OLD := L_RESET;
    AUT_ON_OLD := AUT_ON;
    MAN_ON_OLD := MAN_ON;
    QSTARTING_OLD:= QSTARTING;
    QSTOPPING_OLD:= QSTOPPING;

    //reset commands ================================================
    OP_dwCmd := 16#0;
END_FUNCTION_BLOCK

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值