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校驗用變量的高低字節
CrcCheckCode : 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_WORD(#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_WORD(IN := #CrcTable[#CrcTableIndex], N := int#1);
#CrcTable[#CrcTableIndex] := #CrcTable[#CrcTableIndex] XOR WORD#16#A001;
ELSE
#CrcTable[#CrcTableIndex] := SHR_WORD(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_WORD(IN := #CrcVariable, N := INT#8) XOR #CrcTable[#CrcTableIndex]; //得到CRC校驗變量
END_FOR;
#CrcCheckCode := ROR_WORD(IN := #CrcVariable, N := INT#8); //得到最終CRC校驗碼
//經測試,在CPU315-2 PN/DP中工作,此查表法僅為同環境下計算法的PLC循環時間的五分之一
//此文本復制到TXT,改擴展名為scl,導入源文件就可以,首次掃描脈沖需要創建一下
END_FUNCTION_BLOCK
[ 此帖被wlmissyou在2020-09-25 11:30重新編輯 ]