工控编程吧

标题: SCL编写模拟量监视功能块,用于S7-300 [打印本页]

作者: baikhgmv    时间: 2016-9-27 13:28
标题: SCL编写模拟量监视功能块,用于S7-300
SCL编写模拟量监视功能块,用于S7-300

//编译选项

//Compile options

{

Scl_OverwriteBlocks:=           'y' ;

Scl_CreateObjectCode:=          'y' ;

Scl_OptimizeObjectCode:=        'y' ;

Scl_MonitorArrayLimits:=        'y' ;

Scl_CreateDebugInfo :=          'y'  

}


FUNCTION_BLOCK MonAn

TITLE='Analog Monitoring'

NAME:MonAn

FAMILY:MyLib

AUTHOR:NC

VERSION:'1.0'

// KNOW_HOW_PROTECT

VAR_INPUT

   

    PV   : REAL := 0.0;    //Process Value

    PV_Unit {S7_m_c:='true'}  : INT:=1001 ;  // Unit 单位

    SimOn: BOOL := FALSE;  //Simalation On 仿真打开

    SimPV{S7_m_c:='true'}  : REAL := 0.0;   // Simulation Value 仿真值

    PVHR {S7_m_c:='true'}  : REAL := 100.0; // high range 过程值量程上限

    PVLR {S7_m_c:='true'}  : REAL := 0.0;   // low range过程值量程下限

    HHA  {S7_m_c:='true'}  : REAL := 95.0;  // H limit Alarm 高高报警

    HW   {S7_m_c:='true'}  : REAL := 90.0;  // H limit Warning 高警告

    LW   {S7_m_c:='true'}  : REAL := 10.0;  // L limit Warning 低警告

    LLA  {S7_m_c:='true'}  : REAL := 5.0;   // L Limit Alarm 低低报警

    HHA_EN : BOOL := TRUE;  // H Alarm Message Enable 高高报警消息使能

    HW_EN  : BOOL := TRUE;  // H Warning Message Enable 高警告消息使能

    LW_EN  : BOOL := TRUE;  // L Warning Message Enable 低警告消息使能

    LLA_EN : BOOL := TRUE;  // L Alarm Message Enable 低低报警消息使能

    Hys      {S7_m_c:='true'}  : REAL:=0.0;    // Hysterese value 滞后

    Deadband {S7_m_c:='true'}  : REAL:=0.0 ;   // Width of Dead band 零点死区

    ADCT  : REAL:=0.0;      // Alarm delay coming time 报警延迟到达时间

    WDCT  : REAL:=0.0;      // Warning delay coming time警告延迟到达时间

    ADGT  : REAL:=0.0;      // Alarm delay going time警告延迟离开时间

    WDGT  : REAL:=0.0;      // Warning delay going time报警延迟离开时间

    SAMPLE_T : REAL := 0.2; // Sampletime采样时间

    PULSE    : BOOL;//脉冲输入

//消息事件ID号

    MsgEvID1   {S7_a_type:='alarm_s';S7_server:='alarm_archiv'}  WORD:=DW#16#0;

    MsgEvID2   {S7_a_type:='alarm_s';S7_server:='alarm_archiv'}  WORD:=DW#16#0;

    MsgEvID3   {S7_a_type:='alarm_s';S7_server:='alarm_archiv'}  WORD:=DW#16#0;

    MsgEvID4   {S7_a_type:='alarm_s';S7_server:='alarm_archiv'}  WORD:=DW#16#0;

    SD1 :ANY;

    SD2 :ANY;

    SD3 :ANY;

    SD4 :ANY;

    END_VAR


VAR_IN_OUT

    OP_dwCmd  {S7_m_c:='true'} : DWORD :=16#0;   // control word wincc操作命令

END_VAR


VAR_OUTPUT

    QdwState{S7_m_c:='true'}   : DWORD:=0;             // Status WinCC状态字

    QabyState AT QdwState : ARRAY [0..3] OF BYTE;    // look at state byte-wise

    QdwPerm   {S7_m_c:='true'}: DWORD :=16#FFFFFFFF;   // Permssion word wincc权限字

    QabyPerm AT QdwPerm: ARRAY [0..3] OF BYTE;

    PV_OUT {S7_m_c:='true';S7_archive:='shortterm'} : REAL := 0.0; // Process Value out

    QHHA    : BOOL := FALSE;  // H Alarm is Active //高高报警到达

    QHW     : BOOL := FALSE;  // H Warning is Active//高警告到达

    QLW     : BOOL := FALSE;  // L Warning is Active//低警告到达

    QLLA    : BOOL := FALSE;  // L Alarm is Active//低低警告到达

    QHys    : REAL := 0.0;   //滞后值                           


END_VAR


VAR

    //操作命令高低字节交换需要,以及AT指令拆分DWORD为32个BOOL变量

    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;


    //状态字AT指令拆分DWORD为32个BOOL变量

    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


    //权限字AT指令拆分DWORD为32个BOOL变量

    QdwPermPLC : DWORD := 16#FFFFFFFF;  

    QabyPermPLC AT QdwPermPLC : ARRAY [0..3] OF BYTE;   // look at state byte-wise

    QabPermPLC AT QdwPermPLC : ARRAY [0..31] OF BOOL;   // look at state bit-wise

    //警告及报警延时到达或离开计时器

    ADCT1 : REAL:= 0.0;  // Alarm delay coming time

    WDCT1 : REAL:= 0.0;  // Warning delay coming time

    ADGT1 : REAL:= 0.0;  // Alarm delay going time

    WDGT1 : REAL:= 0.0;  // Warning delay going time

    FP_Pulse:BOOL; //脉冲上升沿

    FP_1,FP_2,FP_3,FP_4:BOOL;

    HHLLA_C,HHLLA_G,HLW_G,HLW_C:BOOL;

    // First scan

    FstScan : BOOL := TRUE; //首次扫描

    RunUpCyc: INT  := 5; //运行周期预设值

    //Message

    MsgEffOld:BYTE:=B#16#0; //消息字节状态存储

    MsgEff:BYTE:=B#16#0; //当前消息字节

    MsgEff1 AT MsgEff :ARRAY[0..7]OF BOOL;

END_VAR


VAR_TEMP

    iRet1,iRet2,iRet3,iRet4:INT;

END_VAR  


-




作者: baikhgmv    时间: 2016-9-27 13:28
-----------------
BEGIN;
//S7300/400以及采用CFC编程方式不同,启动程序不一样,S7300启动运行周期递减为
//启动时减负CPU,不调用AlarmSQ功能块
   IF RunUpCyc > 0 THEN
      RunUpCyc:=RunUpCyc - 1;
   END_IF;   
//交换操作双字高低字节
// 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 ***************************************************
//面板选择使能消息复选框
    IF (OPabCmdPLC[12] ) THEN
        HHA_EN := NOT  HHA_EN;
    END_IF;
               
    IF (OPabCmdPLC[13] ) THEN
         HW_EN := NOT  HW_EN;
    END_IF;
               
    IF (OPabCmdPLC[14] ) THEN
         LW_EN := NOT  LW_EN;
    END_IF;
                                 
    IF (OPabCmdPLC[15] ) THEN
        LLA_EN := NOT  LLA_EN;
    END_IF;   
//仿真操作
    IF OPabCmdPLC[10]  THEN
       SimOn:= TRUE;
    ELSIF  OPabCmdPLC[11]  THEN
       SimOn:= FALSE;
    END_IF;               
// END: Operation functions *****************************************************

//滞后,按百分比计算   
    QHys := Hys * (PVHR - PVLR) / 100.0;
//过程值的选择(仿真值/过程值)
    IF SimOn THEN
       PV_OUT:=SimPV;
    ELSE
       PV_OUT:=PV;
    END_IF;
//零点死区,切除小信号         
   IF ABS(PV_OUT) <= Deadband THEN
       PV_OUT:=0.0 ;
   END_IF;  
//报警以及警告到达上升沿复位计时器
    HHLLA_C:=  ((PV_OUT >= HHA) AND HHA_EN ) OR
               ((PV_OUT <= LLA) AND LLA_EN );
    HLW_C  :=  ((PV_OUT >= HW ) AND HW_EN  ) OR
               ((PV_OUT <= LW ) AND LW_EN  );  
               
    HHLLA_G:=  ((PV_OUT < (HHA - QHys)) AND HHA_EN ) OR
               ((PV_OUT > (LLA + QHys)) AND LLA_EN );
    HLW_G  :=  ((PV_OUT < (HW  - QHys)) AND HW_EN  ) OR
               ((PV_OUT > (LW  + QHys)) AND LW_EN  );
   
    IF HHLLA_C AND NOT FP_1 THEN  ADCT1:=0.0; END_IF;
    IF HLW_C   AND NOT FP_2 THEN  WDCT1:=0.0; END_IF;
    IF HHLLA_G AND NOT FP_3 THEN  ADGT1:=0.0; END_IF;
    IF HLW_G   AND NOT FP_4 THEN  WDGT1:=0.0; END_IF;   
//高高报警的到达以及离开      
    IF HHA_EN THEN      
             IF (PV_OUT >= HHA) AND NOT  QHHA AND PULSE AND NOT FP_Pulse THEN
                ADCT1:=ADCT1+SAMPLE_T;
                IF ADCT1 > ADCT THEN
                QHHA := TRUE;
                ADCT1:= 0.0;
                END_IF;
            ELSIF (PV_OUT < (HHA - QHys))AND QHHA AND PULSE AND NOT FP_Pulse  THEN
                ADGT1:=ADGT1+SAMPLE_T;
                IF ADGT1 > ADGT THEN
                QHHA := FALSE;
                ADGT1:= 0.0;
                END_IF;   
            END_IF;
     ELSE
         QHHA:=FALSE;
     END_IF;
//高警告的到达以及离开            
     IF HW_EN THEN
            IF (PV_OUT >= HW) AND NOT  QHW AND PULSE AND NOT FP_Pulse THEN
                WDCT1:=WDCT1+SAMPLE_T;
                IF WDCT1 > WDCT THEN
                QHW := TRUE;
                WDCT1:=0.0;
                END_IF;
            ELSIF (PV_OUT < (HW - QHys))AND QHW AND PULSE AND NOT FP_Pulse  THEN
                WDGT1:=WDGT1+SAMPLE_T;
                IF WDGT1 > WDGT THEN
                QHW := FALSE;
                WDGT1:=0.0;
                END_IF;
            END_IF;
       ELSE
            QHW:=FALSE;
       END_IF;           
//LW ============================================================
  IF LW_EN then
            IF (PV_OUT <= LW) AND NOT  QLW AND PULSE AND NOT FP_Pulse THEN
                WDCT1:=WDCT1+SAMPLE_T;
                IF WDCT1 > WDCT THEN
                QLW := TRUE;
                WDCT1:=0.0;
                END_IF;
            ELSIF (PV_OUT > (LW + QHys))AND QLW AND PULSE AND NOT FP_Pulse  THEN
                WDGT1:=WDGT1+SAMPLE_T;
                IF WDGT1 > WDGT THEN
                QLW := FALSE;
                WDGT1:=0.0;
                END_IF;   
            END_IF;
    ELSE
        QLW:=FALSE;
    END_IF;              
//LLA ============================================================
    IF LLA_EN THEN
            IF (PV_OUT <= LLA ) AND NOT  QLLA AND PULSE AND NOT FP_Pulse THEN
                ADCT1:=ADCT1+SAMPLE_T;
                IF ADCT1 > ADCT THEN
                QLLA := TRUE;
                ADCT1:=0.0;
                END_IF;
            ELSIF (PV_OUT > (LLA + QHys))AND QLLA AND PULSE AND NOT FP_Pulse  THEN
                ADGT1:=ADGT1+SAMPLE_T;
                IF ADGT1 > ADGT THEN
                QLLA := FALSE;
                ADGT1:=0.0;
                END_IF;
            END_IF;
    ELSE
        QLLA:=FALSE;
    END_IF;  
//操作按钮的权限控制            
    QabPermPLC[10] := NOT SimOn ;   
    QabPermPLC[11] :=     SimOn ;
   
    QabyPerm[0] :=QabyPermPLC[3];
    QabyPerm[1] :=QabyPermPLC[2];
    QabyPerm[2] :=QabyPermPLC[1];
    QabyPerm[3] :=QabyPermPLC[0];
//状态字
    QabStatePLC[0]  := QHHA;     // H Alarm is active  
    QabStatePLC[1]  := QHW;      // H Warning is active
    QabStatePLC[2]  := QLW;      // L Warning is active   
    QabStatePLC[3]  := QLLA;     // L Alarm is active
    QabStatePLC[4]  := 0;         
    QabStatePLC[5]  := 0;     
    QabStatePLC[6]  := 0;   
    QabStatePLC[7]  := 0;
    QabStatePLC[8]  := 0;      
    QabStatePLC[9]  := 0;   
    QabStatePLC[10] := 0;     // Simulation ON
    QabStatePLC[11] := 0;
    QabStatePLC[12] := HHA_EN;    // 1=H Alarm Message enable
    QabStatePLC[13] := HW_EN;     // 1=H Warning Message enable
    QabStatePLC[14] := LW_EN;     // 1=L Warning Message enable
    QabStatePLC[15] := LLA_EN;    // 1=L Alarm Message enable  
    QabStatePLC[16] := 0;
    QabStatePLC[17] := 0;
    QabStatePLC[18] := SimOn;           
    QabStatePLC[19] := 0;
    QabStatePLC[20] := 0;
    QabStatePLC[21] := 0;
    QabStatePLC[22] := 0;
    QabStatePLC[23] := 0;
    QabStatePLC[24] := 0;  
    QabStatePLC[25] := 0;      
    QabStatePLC[26] := 0;        
    QabStatePLC[27] := 0;         
    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];
//报警消息处理
         MsgEff1[0]:=QHHA;
         MsgEff1[1]:=QHW;
         MsgEff1[2]:=QLW;
         MsgEff1[3]:=QLLA;
         MsgEff1[4]:=FALSE;
         MsgEff1[5]:=FALSE;
         MsgEff1[6]:=FALSE;
         MsgEff1[7]:=FALSE;      
   IF (RunUpCyc = 0)  AND (MsgEffOld<>MsgEff)THEN   
            IF (MsgEff AND 16#01) <> ( MsgEffOld AND 16#01)THEN
            iRet1:=  ALARM_SQ(SIG := MsgEff1[0]  // IN: BOOL
                     ,ID :=W#16#EEEE  // IN: WORD
                     ,EV_ID :=MsgEvID1  // IN: DWORD
                     ,SD :=SD1  // IN: ANY
                     ); // INT
            END_IF;
            IF  (MsgEff AND 16#02) <> ( MsgEffOld AND 16#02) THEN   
            iRet2:=   ALARM_SQ(SIG :=MsgEff1[1]   // IN: BOOL
                      ,ID :=W#16#EEEE  // IN: WORD
                      ,EV_ID :=MsgEvID2  // IN: DWORD
                      ,SD :=SD2  // IN: ANY
                      ); // INT
             END_IF;
             IF  (MsgEff AND 16#04) <> ( MsgEffOld AND 16#04)THEN  
             iRet3:=  ALARM_SQ(SIG :=MsgEff1[2]   // IN: BOOL
                     ,ID :=W#16#EEEE  // IN: WORD
                     ,EV_ID :=MsgEvID3  // IN: DWORD
                     ,SD :=SD3  // IN: ANY
                     ); // INT  
             END_IF;   
             IF  (MsgEff AND 16#08) <> ( MsgEffOld AND 16#08)THEN  
             iRet4:=  ALARM_SQ(SIG :=MsgEff1[3]   // IN: BOOL
                     ,ID :=W#16#EEEE  // IN: WORD
                     ,EV_ID :=MsgEvID4  // IN: DWORD
                     ,SD :=SD4  // IN: ANY
                     ); // INT  
             END_IF;                                             
    END_IF;  
    MsgEffOld:=MsgEff ;  
    //上升沿检测     
    FP_1 := HHLLA_C;
    FP_2 := HLW_C;
    FP_3 := HHLLA_G;
    FP_4 := HLW_G;
    FP_Pulse := Pulse;
   //复位操作命令
    OP_dwCmd := 16#0;   
END_FUNCTION_BLOCK


----------接口属性介绍:
1. 变量自动上传
PVHR {S7_m_c:='true'}  : REAL := 100.0; // high range 过程值量程上限
S7_m_c属性相信大家都知道了,OS编辑的时候被标记该属性接口将会自动上传到wincc
2. 变量自动归档
PV_OUT {S7_m_c:='true';S7_archive:='shortterm'} : REAL := 0.0; // Process Value out
S7_archive:='shortterm'在OS编辑会被自动例进TagLogging的表格里,默认1s的归档速度
3. 报警消息自动生成
MsgEvID1   {S7_a_type:='alarm_s';S7_server:='alarm_archiv'}  WORD:=DW#16#0;
S7_a_type:='alarm_s';S7_server:='alarm_archiv'其中Alarm_S是报警功能块类型S7-300由于不支持Alarm_8P,所以选择1路报警Alarm_SQ,S7_a_type与S7_server必须配合使用,OS编译后
能将消息上传至AlarmLogging消息列表。





欢迎光临 工控编程吧 (https://www.gkbc8.com/) Powered by Discuz! X3.4