STM32
直播中

李猛

8年用户 1604经验值
私信 关注
[问答]

ST25TA手册上的RF帧CRC计算,ISO/IEC13239中哪一个呢?

手册上看到是这样的说明,NFC forum 4标签的指令格式带有的CRC应该要按这个来计算,发送。有用过这算法的吗

回帖(1)

刘敏

2025-8-18 16:40:03

针对 ST25TA 手册中 RF 帧的 CRC 计算以及它与 ISO/IEC 13239 和 NFC Forum Type 4 标签的关系,你的理解非常正确。让我来详细解释一下:




  1. 核心标准:ISO/IEC 13239



    • ST25TA 手册中明确指出的 CRC as defined per ISO/IEC 13239 就是你需要的核心规范。

    • ISO/IEC 13239 标准定义了用于数据链路层(如 HDLC)的 CRC 算法。它本身指定了多项式和计算过程,但包含了两种常见的变体

      • 初始值为 0xFFFF + 结果不取反 (not reflected):这个变体通常被称为 CRC-16/CCITT-FALSE 或 CRC-16/AUTOSAR。

      • 初始值为 0x0000 + 结果取反 (reflected):这个变体通常被称为 CRC-16/KERMIT, CRC-16/CCITT, CRC-16/CCITT-TRUE, 或 CRC-CCITT (0x1021)。





  2. ST25TA (及 NFC Forum Type 4) 使用的具体变体:CRC-16/KERMIT



    • ST25TA 手册中描述的细节(初始值 0x0000, 输入数据反转 (reflected input), 输出 CRC 反转 (reflected output), 最后与 0x0000 异或)精确匹配 ISO/IEC 13239 标准中定义的 CRC-16/KERMIT 变体。

    • 关键特征:

      • 多项式 (Polynomial): 0x1021 (十六进制表示,实际参与移位寄存器计算的位模式是 0x8408,因为它包含了隐式的最高位 1 并且输入数据是反射的)。

      • 初始值 (Initial Value): 0x0000

      • 输入数据反射 (Reflect Input): (每个字节的比特顺序在处理前被反转,例如字节 0x01 (二进制 00000001) 被当作 0x80 (二进制 10000000) 来处理)。

      • 输出 CRC 反射 (Reflect Output): (计算得到的 16 位 CRC 寄存器值的比特顺序被整体反转)。

      • 最终异或值 (Final XOR Value): 0x0000





  3. 为什么手册这么说?



    • 手册表述 CRC as defined per ISO/IEC 13239 在技术上是准确的,因为它引用了定义该算法的标准。

    • 然而,ISO/IEC 13239 内部包含不同初始值和反射选项的变体,这可能导致混淆。

    • 手册随后提供的具体细节(初始值 0x0000, 输入/输出反射)明确指定了它使用的是 ISO/IEC 13239 标准下的 CRC-16/KERMIT 变体。这是 NFC Forum Type 4 Tag 操作规范要求的 CRC 算法。




  4. 与 NFC Forum Type 4 Tag 的关系



    • 完全一致。 NFC Forum Type 4 Tag Operation Specification 明确要求所有命令帧和响应帧使用 ISO/IEC 13239 定义的 CRC,具体就是 CRC-16/KERMIT 变体 (初始值 0x0000, 输入输出反射, 最终 XOR 0x0000)

    • ST25TA 作为兼容 NFC Forum Type 4 的标签,其 RF 接口完全遵循该规范。因此,你为 ST25TA RF 帧计算的 CRC 必须使用这个算法,并且也必须按照规范要求,在发送/接收时将 CRC 的两个字节作为帧的一部分包含进去。




总结:



  • ST25TA 手册中要求的 CRC as defined per ISO/IEC 13239 具体指的是该标准下的 CRC-16/KERMIT 变体。

  • 这个算法是 NFC Forum Type 4 Tag 规范强制要求的

  • 关键参数:

    • 多项式: 0x1021 (隐含最高位 1, 实际移位寄存器计算因反射输入使用位模式 0x8408)

    • 初始值: 0x0000

    • 输入数据反射: (按字节)

    • 输出CRC反射:

    • 最终XOR值: 0x0000



用过吗?是的!非常常用!


在 NFC 开发,特别是涉及 Type 4 Tags (无论是 ST25TA, NTAG 4xx 还是其他兼容标签) 或模拟 Type 4 Tag 的设备 (如手机 Host Card Emulation) 时,这个 CRC-16/KERMIT 算法是必须实现和使用的。它是底层 RF 通信帧校验的基础。


如何实现/验证:



  1. 算法库: 大多数编程语言都有 CRC 计算库。你需要找到或指定使用 CRC-16/KERMITCRC-16/CCITT-TRUE (REFLECT_INPUT=True, REFLECT_OUTPUT=True, INIT=0x0000, XOROUT=0x0000)。

  2. 在线计算器: 搜索 CRC-16/KERMIT calculatorCRC-16/CCITT-TRUE calculator。输入你的数据(不带 CRC 部分的命令帧或响应帧数据),看计算结果是否与期望的一致。

  3. 测试向量: 使用已知正确的输入输出进行测试。一个经典的测试向量:

    • 数据: 0x00, 0x00

    • 期望 CRC: 0x84, 0x0C (注意:在帧中传输时通常是低字节在前,即先发 0x0C,再发 0x84。但 CRC 寄存器值 计算结果是 0x0C84,反射后是 0x2180?  ? 这里需要更精确地定义"结果")。重要更正: 对于 CRC-16/KERMIT 处理 0x00, 0x00

      • 初始寄存器 0x0000

      • 处理第一个字节 0x00 (反射后仍是 0x00)

      • 处理第二个字节 0x00 (反射后仍是 0x00)

      • 此时寄存器值应为 0x0000

      • 反射输出:反射 0x0000 还是 0x0000

      • 最终 XOR 0x0000:结果 0x0000


    • 标准测试向量通常是 "123456789" 的 ASCII 字节序列 (0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39),其 KERMIT CRC 应为 0x2189。计算过程后寄存器值是 0x8914,反射输出后是 0x2189

    • ST25TA/NFC Type 4 更实用的测试向量: 可以参考标准或使用已知正确的命令测试。例如,一个空的 SELECT (by file ID) 指令 (CLA=0x00, INS=0xA5, P1=0x00, P2=0x00, Lc=0x02, FileID=0xE1, 0x03) 帧数据部分 (0x00 0xA5 0x00 0x00 0x02 0xE1 0x03) 的 CRC 应该是 0xAF 0x9C (LRC 在前)。



发送顺序:


计算出的 CRC 值(例如 0x2189)在添加到 RF 帧中发送时,按照 NFC Forum / ST25TA 规范的要求,是低字节在前 (Little-Endian)。即:



  • CRC 寄存器计算/反射/XOR 后的值是 Value = (HighByte << 8) | LowByte

  • 在发送帧中:先发送 LowByte,再发送 HighByte


例如:



  • 计算得到的 CRC 值是 0x2189 (HighByte=0x21, LowByte=0x89)。

  • 在 RF 帧中,紧跟在数据域后面发送的两个字节依次是:0x89, 0x21


结论:


严格按照 ST25TA 手册描述和 NFC Forum Type 4 规范实现 CRC-16/KERMIT (ISO/IEC 13239 with Init=0x0000, RefIn=True, RefOut=True, XorOut=0x0000) 算法,并确保在发送时将 CRC 的两个字节按低字节在前的顺序附加到命令帧数据之后,在接收时同样按此规则校验响应帧的 CRC。这是与 ST25TA 等 Type 4 Tags 进行 RF 通信的基础要求。这个算法在 NFC Type 4 开发中非常常用。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分