SCL_CRC校驗(yàn)程序的實(shí)現(xiàn)

FUNCTION "CRC1" : Void { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT CrcData : Variant; END_VAR VAR_OUTPUT CrcValue : Word; CrcErr : Word; END_VAR VAR_TEMP Preset : Word; LoopLength : Int; ArrayPoint : Int; i : Int; ArrayLength : UDInt; Array1 : Array[0..999] of Byte; // 最多1000個(gè)字節(jié) Err : Int; END_VAR BEGIN #ArrayLength:= CountOfElements(#CrcData); IF #ArrayLength <= 1000 THEN //這里的1000如果需要調(diào)大,對(duì)應(yīng)的數(shù)組臨時(shí)變量Array1也要調(diào)大 #Err := MOVE_BLK_VARIANT(SRC := #CrcData, COUNT := #ArrayLength, SRC_INDEX := 0, DEST_INDEX := 0, DEST => #Array1); #Preset := 16#FFFF; #LoopLength := 0; #ArrayPoint := 0; //計(jì)算CRC校驗(yàn)碼 WHILE #LoopLength < #ArrayLength DO //數(shù)據(jù)長(zhǎng)度 #Preset := #Preset XOR #Array1[#ArrayPoint]; #ArrayPoint := #ArrayPoint + 1; FOR #i := 0 TO 7 DO IF (#Preset AND 16#01) = 16#01 THEN #Preset := SHR(IN := #Preset, N := 1); #Preset := #Preset XOR 16#A001; ELSE #Preset := SHR(IN := #Preset, N := 1); END_IF; END_FOR; #LoopLength := #LoopLength + 1; END_WHILE; //#CrcValue := #Preset; #CrcValue := SHR_WORD(IN := #Preset, N := 8) + SHL_WORD(IN := #Preset, N := 8); #CrcErr := 16#0000; ELSE #CrcErr := 16#8000; END_IF; END_FUNCTION
DATA_BLOCK "SEND1"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
STRUCT
CrcData : Array[0..5] of Byte; // 該數(shù)組不大于1000字節(jié)
CrcValue : Word;
CrcError : Word;
END_STRUCT;
BEGIN
CrcData[0] := 16#01;
CrcData[1] := 16#03;
CrcData[2] := 16#00;
CrcData[3] := 16#00;
CrcData[4] := 16#00;
CrcData[5] := 16#01;
END_DATA_BLOCK
FUNCTION "CRC2" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Command : Variant;
dataLen : Int;
END_VAR
VAR_TEMP
buffer : Array[0..#MaxLen] of Byte;
i : Int;
j : Int;
CrcReg : Word;
Len : Int;
END_VAR
VAR CONSTANT
MaxLen : Int := 255;
END_VAR
BEGIN
IF #dataLen = 0 OR #dataLen > CountOfElements(IN := #Command) - 2 THEN
RETURN;
ELSE
#Len := #dataLen;
END_IF;
#CrcReg := 16#FFFF;
//將數(shù)據(jù)轉(zhuǎn)到緩沖區(qū)
VariantGet(SRC:=#Command,
DST=>#buffer);
//計(jì)算CRC校驗(yàn)碼
FOR #i := 0 TO (#Len - 1) DO
#CrcReg := #CrcReg XOR #buffer[#i];
FOR #j := 0 TO 7 DO
IF (#CrcReg AND 16#1) = 1 THEN
#CrcReg := SHR_WORD(IN := #CrcReg, N := 1);
#CrcReg := #CrcReg XOR 16#A001;
ELSE
#CrcReg := SHR_WORD(IN := #CrcReg, N := 1);
END_IF;
END_FOR;
END_FOR;
#buffer[#Len + 1] := SHR_WORD(IN := #CrcReg, N := 8);
#buffer[#Len] := #CrcReg AND 16#FF;
//將緩沖區(qū)數(shù)據(jù)再寫(xiě)入到指針?biāo)赶虻膮^(qū)域
VariantPut(SRC := #buffer,
DST := #Command);
END_FUNCTION
DATA_BLOCK "SEND2"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
STRUCT
CrcData : Array[0..7] of Byte; // 該數(shù)組不大于1000字節(jié)
END_STRUCT;
BEGIN
CrcData[0] := 16#01;
CrcData[1] := 16#03;
CrcData[2] := 16#00;
CrcData[3] := 16#00;
CrcData[4] := 16#00;
CrcData[5] := 16#01;
END_DATA_BLOCK