ISO 14443-A CRC_A计算例子

##个人愚钝,之前刚开始看CRC_A愣是花了大半天才搞懂怎么个事儿;
##今天正巧刷到,就想着写个CRC_A的计算例子,免得以后又忘记了;
##欢迎勘正,先谢过各位的指导


引用

https://blog.csdn.net/u013912838/article/details/139335177
链接的大佬给出了多种NFC的CRC代码,思路非常直观

image

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. 位1: 0110_0011_0111_0001 最低位为1, 右移一位,与0x8408异或
    右移 = 0011_0001_1011_1000
    poly = 1000_0100_0000_1000
    异或 = 1011_0101_1011_0000 = 0xb5b0

  2. 位2:1011_0101_1011_0000 最低位为0,右移不异或
    右移 = 0101_1010_1101_1000 = 0x5ad8

  3. 位3: 0101_1010_1101_1000 最低位为0
    右移 = 0010_1101_0110_1100 = 0x2d6c

  4. 位4: 0010_1101_0110_1100 最低位为0
    右移 = 0001_0110_1011_0110 = 0x16b6

  5. 位5: 0001_0110_1011_0110 最低位为0
    右移 = 0000_1011_0101_1011 = 0x0b5b

  6. 位6: 0000_1011_0101_1011 最低位为1,右移并异或
    右移 = 0000_0101_1010_1101
    poly = 1000_0100_0000_1000
    异或 = 1000_0001_1010_0101 = 0x81a5

  7. 位7: 1000_0001_1010_0101 最低位为1,右移并异或
    右移 = 0100_0000_1101_0010
    poly = 1000_0100_0000_1000
    异或 = 1100_0100_1101_1010 = 0xc4da

  8. 位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. 位1: 0110_0010_0101_1001 最低位为1
    右移 = 0011_0001_0010_1100
    poly = 1000_0100_0000_1000
    异或 = 1011_0101_0010_0100 = 0xb524

  2. 位2: 1011_0101_0010_0100 最低位为0
    右移 = 0101_1010_1001_0010 = 0x5a92

  3. 位3: 0101_1010_1001_0010 最低位为0
    右移 = 0010_1101_0100_1001 = 0x2d49

  4. 位4: 0010_1101_0100_1001 最低位为1
    右移 = 0001_0110_1010_0100
    poly = 1000_0100_0000_1000
    异或 = 1001_0010_1010_1100 = 0x92ac

  5. 位5: 1001_0010_1010_1100 最低位为0
    右移 = 0100_1001_0101_0110 = 0x4956

  6. 位6: 0100_1001_0101_0110 最低位为0
    右移 = 0010_0100_1010_1011 = 0x24ab

  7. 位7: 0010_0100_1010_1011 最低位为1
    右移 = 0001_0010_0101_0101
    poly = 1000_0100_0000_1000
    异或 = 1001_0110_0101_1101 = 0x965d

  8. 位8: 1001_0110_0101_1101 最低位为1
    右移 = 0100_1011_0010_1110
    poly = 1000_0100_0000_1000
    异或 = 1100_1111_0010_0110 = 0xcf26

以此完成0x12,0x34的CRC_A计算,与协议中示例相符合

posted @ 2025-03-07 23:05  wellew  阅读(238)  评论(0)    收藏  举报