ISO 14443-A CRC_A计算例子
##个人愚钝,之前刚开始看CRC_A愣是花了大半天才搞懂怎么个事儿;
##今天正巧刷到,就想着写个CRC_A的计算例子,免得以后又忘记了;
##欢迎勘正,先谢过各位的指导
引用
https://blog.csdn.net/u013912838/article/details/139335177
链接的大佬给出了多种NFC的CRC代码,思路非常直观

CRC_A的poly是0x1021, 计算中采用二进制翻转后的值0x8408;
之所以需要针对poly做翻转处理,是因为14443-A Tag为小端发送。初始值和Data由电路完成发送,为LSB格式。相应的,poly一般会在计算过程中固定,所以应让其也转换成LSB表达格式即对0x1021二进制翻转,得到0x8408
CRC_A简介
CRC A的生成多项式为x16+x12+x5+1,校验位位宽应为16bit,两字节crc_lsb和crc_msb。
仅校验数据。SOF、EOF和P均不参与CRC计算。
初始值采用0x6363,计算结果不翻转(二进制翻转)。
计算得到的结果拼接在通信帧后,且每8位,即一个字节后正常拼接P。
计算例子
以ISO/IEC 14443-3附录B的内容为例子。


输入数据为0x12和0x34;根据官方协议,其CRC结果应为0xCF26;
下面展开计算过程:
-
初始 CRC = 0x6363 = 0110_0011_0110_0011
-
处理第一个字节 (0x12 = 0001_0010),与初始值0x6363异或
CRC = 0110_0011_0110_0011
字节 = 0000_0000_0001_0010
异或 = 0110_0011_0111_0001 = 0x6371 -
八位循环处理
-
位1: 0110_0011_0111_0001 最低位为1, 右移一位,与0x8408异或
右移 = 0011_0001_1011_1000
poly = 1000_0100_0000_1000
异或 = 1011_0101_1011_0000 = 0xb5b0 -
位2:1011_0101_1011_0000 最低位为0,右移不异或
右移 = 0101_1010_1101_1000 = 0x5ad8 -
位3: 0101_1010_1101_1000 最低位为0
右移 = 0010_1101_0110_1100 = 0x2d6c -
位4: 0010_1101_0110_1100 最低位为0
右移 = 0001_0110_1011_0110 = 0x16b6 -
位5: 0001_0110_1011_0110 最低位为0
右移 = 0000_1011_0101_1011 = 0x0b5b -
位6: 0000_1011_0101_1011 最低位为1,右移并异或
右移 = 0000_0101_1010_1101
poly = 1000_0100_0000_1000
异或 = 1000_0001_1010_0101 = 0x81a5 -
位7: 1000_0001_1010_0101 最低位为1,右移并异或
右移 = 0100_0000_1101_0010
poly = 1000_0100_0000_1000
异或 = 1100_0100_1101_1010 = 0xc4da -
位8: 1100_0100_1101_1010 最低位为0
右移 = 0110_0010_0110_1101 = 0x626d
至此,0x12的CRC_A计算完毕,此时的CRC_A寄存器值为0x626d
-
基于0x626d继续进行第二个数据0x34的CRC_A计算:
-
0x32与0x626d异或
CRC = 0110_0010_0110_1101
字节 = 0000_0000_0011_0100
异或 = 0110_0010_0101_1001 = 0x6259 -
八位循环处理
-
位1: 0110_0010_0101_1001 最低位为1
右移 = 0011_0001_0010_1100
poly = 1000_0100_0000_1000
异或 = 1011_0101_0010_0100 = 0xb524 -
位2: 1011_0101_0010_0100 最低位为0
右移 = 0101_1010_1001_0010 = 0x5a92 -
位3: 0101_1010_1001_0010 最低位为0
右移 = 0010_1101_0100_1001 = 0x2d49 -
位4: 0010_1101_0100_1001 最低位为1
右移 = 0001_0110_1010_0100
poly = 1000_0100_0000_1000
异或 = 1001_0010_1010_1100 = 0x92ac -
位5: 1001_0010_1010_1100 最低位为0
右移 = 0100_1001_0101_0110 = 0x4956 -
位6: 0100_1001_0101_0110 最低位为0
右移 = 0010_0100_1010_1011 = 0x24ab -
位7: 0010_0100_1010_1011 最低位为1
右移 = 0001_0010_0101_0101
poly = 1000_0100_0000_1000
异或 = 1001_0110_0101_1101 = 0x965d -
位8: 1001_0110_0101_1101 最低位为1
右移 = 0100_1011_0010_1110
poly = 1000_0100_0000_1000
异或 = 1100_1111_0010_0110 = 0xcf26
以此完成0x12,0x34的CRC_A计算,与协议中示例相符合

浙公网安备 33010602011771号