作者 | 主题 |
---|---|
1Shadow1 侠士 经验值:1130 发帖数:81 精华帖:4 |
楼主 2023-08-25 09:20:38
主题:CRC 练习一. CRC4-ITU_1 最近发现一个比较好的练手题目-CRC 校验;
循环冗余校验码(CRC),简称循环码,是一种常用的、具有检错、纠错能力的校验码,在早期的通信中运用广泛。循环冗余校验码常用于外存储器和计算机同步通信的数据校验。奇偶校验码和海明校验码都是采用奇偶检测为手段检错和纠错的(奇偶校验码不具有纠错能力),而循环冗余校验则是通过某种数学运算来建立数据位和校验位的约定关系的。---------百度百科;
CRC 手动校验的步骤: 1. 确定要使用的多项式,常用的多项式有好多,如下; 2.多项式相关的参数有width, Poly, Init, RefIn/out,XorOut; .比如此次拿CRC-4/ITU为例, Poly:=X4+X+1=10011,扣掉首位后位0x03;Init=0x00; RefIn/out:=true; XorOut:=0x00; 3,以数据0x11为例; 0x11=0b00010001, Init=0x00,不需要对数据前width位进行异或0xFF(取反)操作; RefIn/Out=true; bit按MSB排列,西门子字节本身就是MSB;In的时候注意1.5个byte和2个byte的时候需要处理一下;输出的时候要MSB 切换到LSB,另外最后输出的时候需要偏移一位再输出; XorOut:=false,不用对结果取反;
MOD2: 模2 取余;网上给有好多;下面是我手算的一些;
下面是TIA程序,目前只能计算0x0-0Xffff,;
IF #TestTrigger THEN #step := 1; #TestTrigger := false; END_IF; CASE #step OF 1://Init FOR #i := 0 TO 23 DO IF #i < 3 THEN #tempIndex[#i] := 0; END_IF; IF #i <= 7 THEN #bCurrentDividend[#i] := FALSE; #bCurrentResult[#i] := FALSE; END_IF; IF #i <= 15 THEN #bArray2[#i] := false; END_IF; #bArray3[#i] := false; END_FOR; #Result := 0; #PreIndex := 5;//First index No. after the dividend; #step := 2; 2: // SCATTER(IN := #Input_test, OUT => #bArray2);
FOR #i := 15 TO 0 BY -1 DO //Check Number of digits entered IF #bArray2[#i] THEN IF (#i + 1) MOD 4 > 0 THEN #Space:=(#i + 1)/4+1; ELSE #Space:=(#i + 1)/4; END_IF; EXIT; END_IF; END_FOR;
#step := 3;
3: //RefIn
IF #Space = 3 THEN FOR #i := 0 TO 7 DO #tempb1 := #bArray2[#i]; #bArray2[#i]:=#bArray2[4 + #i] ; #bArray2[4 + #i] := #tempb1; END_FOR; ELSIF #Space=4 THEN FOR #i := 0 TO 7 DO #tempb1 := #bArray2[#i]; #bArray2[#i] := #bArray2[8 + #i]; #bArray2[8 + #i] := #tempb1; END_FOR;
END_IF;
IF #Space <= 1 THEN #Space := 2; ELSIF #Space = 3 THEN #Space := 4; END_IF; #Inventory := #Space * 4 + #Width;
#step := 4; 4://Mod2
FOR #i := 0 TO 15 DO #bArray3[#i] := #bArray2[#i]; END_FOR;
FOR #i := 0 TO #Space*4 DO //Get Non-0 bits to bCurrentDividend from bArray3 for the first time; IF #bArray3[#i] THEN FOR #j := 0 TO 4 DO #bCurrentDividend[#j] := #bArray3[#i+#j]; END_FOR; #PreIndex := #PreIndex + #i; EXIT; END_IF; END_FOR;
WHILE #PreIndex <= #Inventory DO
FOR #i := 0 TO 4 DO #bCurrentResult[#i] := #bCurrentDividend[#i] XOR #bPoly[#i]; //MOD 2 END_FOR;
#ComplementNo := -1; FOR #i := 0 TO 4 DO //Get supplement No. IF #bCurrentResult[#i] THEN #ComplementNo := #i; EXIT; END_IF; END_FOR; IF #ComplementNo = -1 THEN #ComplementNo := 5; END_IF;
IF #ComplementNo < 5 THEN FOR #i := 0 TO 4 - #ComplementNo DO //Move the rest NON-0 bit to currentDividend as first part; #bCurrentDividend[#i] := #bCurrentResult[#ComplementNo + #i]; END_FOR; END_IF;
//Check inventory before take out new bits IF (#PreIndex + #ComplementNo) > #Inventory THEN IF #Inventory - #PreIndex - 1 < 0 THEN EXIT; END_IF;
FOR #i := 0 TO #Inventory - #PreIndex - 1 DO FOR #j := 0 TO 4 DO //#bCurrentResult[5] is zero and stand for the newbits from Array3; #bCurrentResult[#j] := #bCurrentResult[#j + 1]; END_FOR; END_FOR; EXIT; END_IF;
FOR #i := (4+1-#ComplementNo) TO 4 DO//Move new bits to dividend; #bCurrentDividend[#i] := #bArray3[#PreIndex]; //Move new bits from bArray to currentDividend as second part; #PreIndex := #PreIndex + 1; //Point to next available bit IF #PreIndex > #Inventory THEN EXIT; END_IF; END_FOR;
//If last time ComplementNo is 5,then need check the new moved 5 numbers have at least one 1, otherwise the 5 numbers is useless; FOR #i := 0 TO 4 DO IF #bCurrentDividend[#i] THEN IF #i > 0 THEN FOR #j := 0 TO 4-#i DO #bCurrentDividend[#j] := #bCurrentDividend[#i+#j]; END_FOR;
FOR #j := 4 - #i + 1 TO 4 DO #bCurrentDividend[#j] := #bArray3[#PreIndex]; #PreIndex := #PreIndex + 1; IF #PreIndex >= #Inventory THEN EXIT; END_IF; END_FOR; EXIT; ELSE EXIT; END_IF; END_IF; END_FOR;
//It's better to make a EXCEL file to have methods for any possible numbers for CRC16;
END_WHILE; #step := 5; 5: //RefOut
GATHER(IN := #bCurrentResult, //#bCurrentResult[0]=0;[1]->Result.%X0; OUT => #Result); #Result := SHR(IN := #Result, N := 1);
END_CASE; 结果对比:
验证的网站 CRC(循环冗余校验)在线计算_ip33.comhttp://www.ip33.com/crc.html CRC校验工具-ME2在线工具 (metools.info)http://www.metools.info/code/c15.html 最好用第二个,第一个可能不准确。。。 后面练习的方向: 1. 不限长度,用字节数组存储; 2. 简化程序; 3. 用STL 实现; 4. 尝试练习不同种类的Poly; 不准确的地方欢迎指出,有兴趣的小伙伴可以一起练习;
谋定而后动,精益求精。
|