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修订历史记录

误差校正

使用汉明和校验和验证后,可以纠正单个位错误。首先进行数据验证和纠错,如果可能,则纠正位。如果恢复了数据,则重新评估校验和。如果出现多位错误或校验和错误,则传输无效。

uint32_t fixResults[] = {
    0,        // 数据块正常
    1 << 3,   // 数据中没有错误 (H0)
    1 << 4,   // 数据中没有错误 (H1)
    1u << 31, // 数据[23] 错误
    1 << 5,   // 数据中没有错误 (H2)
    1 << 30,  // 数据[22] 错误
    1 << 29,  // 数据[21] 错误
    1 << 28,  // 数据[20] 错误
    1 << 6,   // 数据中没有错误 (H3)
    1 << 27,  // 数据[19] 错误
    1 << 26,  // 数据[18] 错误
    1 << 25,  // 数据[17] 错误
    1 << 24,  // 数据[16] 错误
    1 << 23,  // 数据[15] 错误
    1 << 22,  // 数据[14] 错误
    1 << 21,  // 数据[13] 错误
    1 << 7,   // 数据中没有错误 (H4)
    1 << 20,  // 数据[12] 错误
    1 << 19,  // 数据[11] 错误
    1 << 18,  // 数据[10] 错误
    1 << 17,  // 数据[9] 错误
    1 << 16,  // 数据[8] 错误
    1 << 15,  // 数据[7] 错误
    1 << 14,  // 数据[6] 错误
    1 << 13,  // 数据[5] 错误
    1 << 12,  // 数据[4] 错误
    1 << 11,  // 数据[3] 错误
    1 << 10,  // 数据[2] 错误
    1 << 9,   // 数据[1] 错误
    1 << 8,   // 数据[0] 错误
              // 不可纠正的 30
              // 不可纠正的 31
              // H0 覆盖 14 个位,H1-H4 覆盖 13 个位,
              //   因此如果汉明码为 30 或 31,
              //   则会出现多位错误且无法纠正
};
/**
 * 数据验证和单个位错误修复。
 *
 * \详细信息:使用汉明位信息验证和
 * 恢复数据以纠正单个位错误。  首先检查“in”值,
 * 如果异或运算返回 0,则相对于汉明位验证数据内容,
 * 然后使用校验和检查数据内容是否存在多位错误。
 * 如果汉明位与数据不匹配,则在可能的情况下
 * 使用汉明位来纠正数据,方法是使用计算出的
 * 汉明位与传输的汉明位进行异或。  使用基于校正系数和异或值的查找表
 * 来恢复数据,然后计算校验和以确保没有
 * 多位错误。
 *
 * \参数 uint32_t in 是要计算和比较的值。
 *
 * \返回 uint32_t res,如果数据可纠正或有效,则返回 0。 
 *                        非零值是无效数据。
 */
uint32_t fixHamming(uint32_t in)
{
    uint32_t res;
    uint32_t fix;
    // checkHamming 将从数据“in”返回 5 个汉明位
    // 在条件语句中使用赋值时,条件会对赋值进行
    //    评估。
    // 如果 checkHamming 返回“0”以外的值,则尝试修复结果
    if(res = checkHamming(in))
    {
        // 根据非“0”的汉明码结果,通过调整来自包含
        // 2^5(或 32)种可能组合的表中“in”的 32 位值,
        // 使用查找表来纠正结果。总之,32 个值中有 24 个值用于 1 位纠错,
        // 5 个值表示数据无错误(汉明码中的 1 位错误),1 个值表示
        // 数据和汉明码均无错误,2 个值表示数据、汉明码
        // 或两者中存在多位错误。对于多位错误的情况只分配了
        // 两个值,因此算法很可能错误地
        // 将多位错误视为 1 位错误。为了降低这种
        // 可能性,除了汉明检测之外,还添加了 2 位校验和
        // 以进行检错。
        
        // 快速检查汉明值中是否存在多位错误
        fix = res >> 3;
        // 然后将计算出的汉明位与“in”值汉明位进行异或运算
        fix = fix ^ ((in & 0xFF) >> 3);
        // 如果存在已知的多位错误,则指示修复失败
        if (fix > 29) return HC_FIX_FAIL;
        else
        {
            // 发生了位错误,尝试进行修复
            fix = (fixResults[fix]);
            // 识别的错误可能是汉明错误或数据错误,在此处将“in”值
            //   与 fix 值进行异或
            res = in ^ fix;
        }
    }
    else
    {
        res = in;
    }
    // res 现在包含数据的原始值或修复值,即经过
    // 汉明校验和数据纠正后的数据 + 汉明值,
    // 使用校验和位检查多位错误,checkSum 将
    // 在计数中排除汉明位。如果 checkSum 返回 0 以外的值,则
    // checkSum 失败,否则返回 0
    if(checkSum(res))
    {
        return HC_FIX_FAIL;
    }
    return res;
}