工控编程吧
标题: 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 |