ZHCAAO5A June   2020  – August 2021 ADS112C04 , ADS112U04 , ADS114S06 , ADS114S08 , ADS122C04 , ADS122U04 , ADS1235 , ADS1235-Q1 , ADS124S06 , ADS124S08 , ADS1259 , ADS1259-Q1 , ADS125H01 , ADS125H02 , ADS1260 , ADS1260-Q1 , ADS1261 , ADS1262 , ADS1263 , ADS127L01 , ADS131A02 , ADS131A04 , ADS131M04 , ADS131M06 , ADS131M08

 

  1.   商标
  2. 1引言
  3. 2简单校验和
    1. 2.1 校验和代码示例
  4. 3CRC
    1. 3.1 CRC 通用计算
      1. 3.1.1 使用按位异或计算
      2. 3.1.2 使用查找表
        1. 3.1.2.1 表初始化
        2. 3.1.2.2 CRC 计算
      3. 3.1.3 ADS122U04 和 ADS122C04 之间的 CRC 计算差异
        1. 3.1.3.1 字节反射示例
        2. 3.1.3.2 使用字节反射重新组合数据以进行 CRC 计算
  5. 4汉明码
    1. 4.1 汉明码计算
      1. 4.1.1 汉明码计算示例
        1. 4.1.1.1 计算位数以进行奇偶校验和校验和计算
          1. 4.1.1.1.1 计算数据中置 1 的位的数量示例
          2. 4.1.1.1.2 使用查找表计算置 1 的位的数量示例
      2. 4.1.2 验证传输的数据
        1. 4.1.2.1 汉明验证
        2. 4.1.2.2 校验和验证
        3. 4.1.2.3 误差校正
  6. 5总结
  7. 6参考文献
  8. 7修订历史记录

使用按位异或计算

软件按位运算函数忽略多项式值中的最高位。在对余数进行异或运算之前会将最高位移出,因此可以忽略该位。例如,CRC-16-CCITT 的多项式为 x16 + x12 + x5 + 1 (11021h),由 10001000000100001b 表示。不过,最高位被丢弃,按位运算中用于计算的值变为 1021h。

GUID-E81BC2BA-CE04-499E-B580-1297F7D6C608-low.gif图 3-3 CRC-16-CCITT 硬件实现

对于 8 位 CRC-8-ATM (HEC),多项式是 X8 + X2 + X + 1 (107h),由 100000111b 表示。同样地,最高位被忽略,用于按位运算的值为 7h。

GUID-FBC554D6-168C-4C59-A6A6-68B68D974EA9-low.gif图 3-4 CRC-8-ATM (HEC) 硬件实现

以下代码函数适用于 CRC-16-CCITT,但可以轻松适应其他多项式以及长度。该函数复制硬件实现并根据 CRC 长度的大小返回一个值,该值由 crc_t 的类型定义表示。在该代码示例中,返回值是一个无符号的 16 位值。传递的参数是指向待计算数据 包的指针和数据包的长度 (字节数)。该函数通过与余数执行按位异或运算来处理每个数据字节。REMAINDER_INIT 的初始值是起始种子值,会因使用的 ADC 而异。

typedef uint16_t crc_t;          // 对于 8 位 CRC,使用 uint8_t
#define POLYNOMIAL 0x1021       // CRC16-CCITT,但对于 8 位 CRC,使用 CRC-8-ATM (HEC)
                                 // 和多项式值 0x07
#define REMAINDER_INIT 0xFFFF    // 对于 ADS1xC04 和 ADS1x2U04 上的 16 位 CRC,使用 0xFFFF
                                 // 对于 ADS1260、ADS1261 和 ADS1235 上的 8 位 CRC,使用 0xFF
                                 // 对于 ADS124S0x、ADS114S0x、ADS1262 和 ADS1263 上的 8 位 CRC,使用 0x00
#define WIDTH (8 * sizeof(crc_t))
/**
 * 计算一系列数据字节的 CRC。
 *
 * \详细信息:通过与所需的多项式进行异或运算来计算一系列字节的 CRC。
 *
 * \参数 uint8_t *data 是指向数据数组的指针。
 * \参数 uint32_t length 是数据数组的长度。
 *
 * \返回 crc_t remainder。
 */
crc_t  crcBitwise(uint8_t *data, uint32_t length)
{
    crc_t remainder = REMAINDER_INIT;
    uint32_t byte, bit;
                                                     // 对数据包中的每个字节
                                                     //    执行多项式长除法
    for(byte = 0; byte < length; byte++)
    {
        remainder ^= (data[byte] << (WIDTH - 8));    // 将下一个字节取到余数中
        for(bit = 8; bit > 0; bit--)                 // 对于余数中的每个字节
        {
            if(remainder & (1 << (WIDTH - 1)))
                remainder = (remainder << 1) ^ POLYNOMIAL; // 如果最高位置 1,则将余数
                                                           //   左移并将其与除数异或,
            else                                           //   然后将结果存储
                                                           //   在余数中
                remainder = (remainder << 1);              // 如果最高位清零,则左移
                                                           //    余数
        }
    }
    return remainder;
} 

该代码示例对于确定数据的 CRC 余数很有用。对于具有传入和传出 CRC 数据完整性检查的器件,需要计算出余数。不过,如果仅针对 ADC 的传输验证数据(例如转换数据),则可将传输的 CRC 值添加到数据数组中。如果计算中包含 CRC 余数,并且 CRC 与计算值以及传输值都匹配,则余数将为零。换句话说,CRC 计算有一个重要的特性,即在匹配字节中移位会强制将 CRC 移位寄存器中的值设置为零。非零结果将指示传输错误。使用该方法则无需对传输的 CRC 和计算的 CRC 进行直接比较,从而简化验证。