FUNCTION_BLOCK "CRC"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
VAR
DATA : Array[0..250] of Byte; // 待校验的数据
ByteIndex : Int; // 待校验数据的字节号索引号
CrcBitIndex : Int; // CRC校验表生成中所用的位索引号
CRCvariable : Word; // CRC校验用变量字
CRCbyte { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} AT CRCvariable : Array[0..1] of Byte; // CRC校验用变量的高低字节
"CRCCheck code" : Word; // ***终CRC校验码
CRCtable : Array[0..255] of Word; // CRC校验表
CrcTableIndex : Int; // CRC表的字索引号
END_VAR
BEGIN
//生成CRC校验表
IF "FirstScan" = TRUE THEN //***次扫描时生成CRC表
FOR #CrcTableIndex := INT#0 TO INT#255 BY INT#1 DO
#CRCtable[#CrcTableIndex] := INT_TO_Wor(#CrcTableIndex);
FOR #CrcBitIndex := INT#0 TO INT#7 BY INT#1 DO
IF (#CRCtable[#CrcTableIndex] AND WORD#16#0001) = WORD#16#0001 THEN
#CRCtable[#CrcTableIndex] := SHR_Wor(IN := #CRCtable[#CrcTableIndex], N := int#1);
#CRCtable[#CrcTableIndex] := #CRCtable[#CrcTableIndex] XOR WORD#16#A001;
ELSE
#CRCtable[#CrcTableIndex] := SHR_Wor(IN := #CRCtable[#CrcTableIndex], N := int#1);
END_IF;
END_FOR;
END_FOR;
END_IF;
//CRC循环冗余校验查表法
#CRCvariable := WORD#16#FFFF; //CRC寄存器的初始化
FOR #ByteIndex := INT#0 TO INT#240 BY INT#1 DO //提取待校验的数据
#CrcTableIndex := BYTE_TO_INT((#DATA[#ByteIndex] AND BYTE#16#FF) XOR (#CRCbyte[1] AND BYTE#16#FF)); //生成CRC校验表字的索引号
#CRCvariable := SHR_Wor(IN := #CRCvariable, N := INT#8) XOR #CRCtable[#CrcTableIndex]; //得到CRC校验变量
END_FOR;
#"CRCCheck code" := ROR_Wor(IN := #CRCvariable, N := INT#8); //得到***终CRC校验码
//经测试,在CPU315-2 PN/DP中工作,此查表法仅为同环境下计算法的PLC循环时间的五分之一
//此文本复制到TXT,改扩展名为scl,导入源文件就可以,首次扫描脉冲需要创建一下
END_FUNCTION_BLOCK