[其它应用] 分享一个CRC8的计算实现

[复制链接]
 楼主| 雾里闲逛 发表于 2025-4-27 00:08 | 显示全部楼层 |阅读模式
CRC-8软件实现
以多项式G(X) = X^8+X^2+X^1+1来实现。
  1. #define FACTOR (0x107 & 0xFF) //多项式因子(取低8bit)
  2. unsigned char calcCRC(unsigned char *pdat, unsigned int len)
  3. {
  4.     unsigned char j;
  5.     unsigned char crc = 0x00;
  6.     while(len--)
  7.         {
  8.         crc ^= (*pdat++);//前一字节计算CRC后的结果异或上后一字节,再次计算CRC
  9.         for (j=8; j>0; j--)
  10.         {
  11.                  crc <<= 1;
  12.             if (crc & 0x80)//高位为1,需要异或;否则,不需要
  13.             {
  14.                 crc ^= FACTOR;
  15.             }
  16.         }
  17.     }

  18.     return crc;
  19. }



分形梦想家 发表于 2025-4-27 15:08 | 显示全部楼层
楼主,这个都用在哪些应用上面啊
jobszheng 发表于 2025-4-27 19:47 | 显示全部楼层
分形梦想家 发表于 2025-4-27 15:08
楼主,这个都用在哪些应用上面啊

传输数据或才校验数据小于128字节时,可以使用CRC8算法
分形梦想家 发表于 2025-4-27 20:44 | 显示全部楼层
明白了。
不过,为什么会出错啊
记忆花园 发表于 2025-4-28 18:36 | 显示全部楼层
这个CRC8的算法 很实用的。收下了,谢谢楼主分享
AdaMaYun 发表于 2025-4-29 16:12 | 显示全部楼层
CR8校验学习一下
OKAKAKO 发表于 2025-4-29 16:45 | 显示全部楼层
CRC8的算法 很实用的
银河漫步 发表于 2025-5-8 15:50 | 显示全部楼层
这个校验与校验和算法,哪个更靠谱一下啊
破晓战神 发表于 2025-5-23 18:57 | 显示全部楼层
这个实现很简洁,不过在实际应用中,CRC8的多项式选择和初始化值可能会有所不同,需要根据具体的协议来调整。
穷得响叮当侠 发表于 2025-5-24 09:29 | 显示全部楼层
这个实现看起来是基于C语言的,使用了一个简单的循环来计算CRC8值。代码简洁,易于理解。
 楼主| 雾里闲逛 发表于 2025-5-26 02:57 | 显示全部楼层
银河漫步 发表于 2025-5-8 15:50
这个校验与校验和算法,哪个更靠谱一下啊

针对不同的出错机制与数据量而定。
比如通讯故障CRC校验和校验和的差别不大,毕竟出错的概率都挺低的。
但对于错过错误,这时校验和的就有点力不从心了
又见春光 发表于 2025-7-23 22:16 | 显示全部楼层
参与一下讨论多项式 0x07,初始值 0xFF,适用于 Modbus、I2C 等校验。
uint8_t crc8(const uint8_t *data, uint8_t len) {
  uint8_t crc = 0xFF; // 初始值
  for (int i=0; i<len; i++) {
    crc ^= data[i];
    for (int j=0; j<8; j++)
      crc = (crc << 1) ^ ((crc & 0x80) ? 0x07 : 0);
  }
  return crc;
}


 楼主| 雾里闲逛 发表于 2025-7-29 07:05 | 显示全部楼层
又见春光 发表于 2025-7-23 22:16
参与一下讨论多项式 0x07,初始值 0xFF,适用于 Modbus、I2C 等校验。
uint8_t crc8(const uint8_t *data,  ...

Modbus-RTU使用的可是CRC16哟
绝影孤狼 发表于 2025-8-1 15:43 | 显示全部楼层
这个实现看起来是正确的,你使用了标准的CRC算法来计算CRC8。确保在使用前定义了正确的多项式因子。
1988020566 发表于 2025-8-7 08:52 | 显示全部楼层
CRC8算法的核心是选择一个生成多项式
wwppd 发表于 2025-8-7 09:40 | 显示全部楼层
:在计算CRC8时,通常需要设置一个初始值(如0x00)和一个最终值(如0xFF)。这些值会影响最终的校验和。
kmzuaz 发表于 2025-8-7 10:21 | 显示全部楼层
数据流中的字节是以高位在前(Big-Endian)还是低位在前(Little-Endian)的方式处理
zerorobert 发表于 2025-8-7 12:43 | 显示全部楼层
通过预先计算并存储一个256条目的CRC表,可以快速计算每个字节的CRC值。
janewood 发表于 2025-8-7 15:43 | 显示全部楼层
#include <stdint.h>

// 预计算CRC表
static uint8_t crc8_table[256];
void crc8_init_table() {
    for (int i = 0; i < 256; i++) {
        uint8_t crc = i;
        for (int j = 0; j < 8; j++) {
            if (crc & 0x80) crc = (crc << 1) ^ 0x07;
            else crc <<= 1;
        }
        crc8_table[i] = crc;
    }
}

// 查表法计算CRC
uint8_t crc8_calculate(const uint8_t *data, size_t len) {
    uint8_t crc = 0x00;
    for (size_t i = 0; i < len; i++) {
        crc = crc8_table[crc ^ data[i]];
    }
    return crc;
}
chenci2013 发表于 2025-8-8 11:41 | 显示全部楼层
CRC8 的实现需紧密结合具体协议规范,重点关注多项式、初始值、输入顺序三大核心参数
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

43

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部