之前在论坛里面看到了一个报警信息处理程序觉得很好,就用在设备报警处理程序里,可由于不同设备报警信号数量不同,就需要每次都改一下报警信号点数量。最近忽然觉得可以用Serialize Deserialize来实现把struct里的数据复制到array中,模拟了一下,挺好用。
测试程序如下:(需要说明一下:原程序是论坛里面别人写的)
FUNCTION_BLOCK "Alarm_ProcessFB_SCL_20221205"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Alarm_In : Variant;
END_VAR
VAR_INPUT DB_SPECIFIC
Alarm_Rst : Bool;
Sound_Rst : Bool;
END_VAR
VAR_OUTPUT DB_SPECIFIC
Fault_Rst_Cmd : Bool;
Alarm_Light : Bool;
Alarm_Sound : Bool;
END_VAR
VAR
Alm : Array[0..31] of Word;
END_VAR
VAR DB_SPECIFIC
Alarm_OP : Array[0..31] of Word;
Alarm_Buf : Array[0..31] of Word;
Alarm_Chk_Flg : Bool;
NewAlarm_Chk_Flg : Bool;
Alarm_Flg : Bool;
NewAlarm_Flg : Bool;
Sound_Rst_Fp : Bool;
Sound_Rst_Flg : Bool;
Rst_Cmd_Out_Flg : Bool;
Light_Out_Flg : Bool;
Sound_Out_Flg : Bool;
END_VAR
VAR_TEMP
arr : Array[0..63] of Byte;
Loop_Cnt : Int;
Alarm_RD : Word;
AlarmBuf_RD : Word;
NewAlarm_Value : Word;
New_Alarm : Word;
pos : DInt;
ret : Int;
END_VAR
VAR CONSTANT
Size : Int := 32;
END_VAR
BEGIN
#pos := 0;
#ret:=Serialize(SRC_VARIABLE := #Alarm_In, DEST_ARRAY => #arr, POS := #pos);
#pos := 0;
#ret := Deserialize(SRC_ARRAY := #arr, DEST_VARIABLE => #Alm, POS := #pos);
#Loop_Cnt := 0;
#Alarm_Flg := FALSE;
#NewAlarm_Flg := FALSE;
FOR #Loop_Cnt := 0 TO #Size - 1 BY 1 DO
#Alarm_OP[#Loop_Cnt] := SWAP(#Alm[#Loop_Cnt]);
#Alarm_RD := #Alarm_OP[#Loop_Cnt];
#AlarmBuf_RD := #Alarm_Buf[#Loop_Cnt];
#Alarm_Buf[#Loop_Cnt] := #Alarm_RD;
#New_Alarm := #Alarm_RD XOR #AlarmBuf_RD AND #Alarm_RD;
#Alarm_Chk_Flg := #Alarm_RD <> 16#0;
#NewAlarm_Chk_Flg := #New_Alarm <> 16#0;
#Alarm_Flg := #Alarm_Flg OR #Alarm_Chk_Flg;
#NewAlarm_Flg := #NewAlarm_Flg OR #NewAlarm_Chk_Flg;
END_FOR;
#Sound_Rst_Flg := #Sound_Rst XOR #Sound_Rst_Fp AND #Sound_Rst;
#Sound_Rst_Fp := #Sound_Rst;
#Alarm_Light := #Light_Out_Flg := #Alarm_Flg;
#Alarm_Sound := #Sound_Out_Flg := (#NewAlarm_Flg OR (#Sound_Out_Flg AND NOT #Sound_Rst_Flg)) AND #Alarm_Flg;
#Fault_Rst_Cmd := #Rst_Cmd_Out_Flg := #Alarm_Rst AND #Alarm_Flg;
END_FUNCTION_BLOCK