CRC8校验原理
CRC8校验原理
原理
假设CRC8校验slave address + data byte
传入两个字节的数据(16位)
CRC初始值及校验key查看数据手册 不同芯片有不同的要求
如(BQ76930)
The CRC polynomial is x8 + x2 + x + 1, and the initial value is 0.
因此,初始CRC=0,多项式表示 1 0000 0111 有提到的位为1 最高位不需要参与校验 结果key为0x07
步骤
1、进行两轮循环 每个循环校验8位
2、在for循环中对CRC进行8次处理,从最高位开始 如果CRC为0则左移1位。如果不为0,则CRC先左移1位,然后和key进行异或
3、每个for中都有一次字节ptr(8位)& i 相当于ptr为掩码 从高位到低位轮询 如果为1 则CRC进行异或 否则不进行操作
数据0x11 key0x07 结果0x77
代码
unsigned char CRC8(unsigned char *ptr, unsigned char len,unsigned char key)
{unsigned char i;unsigned char crc=0;while(len--!=0){for(i=0x80; i!=0; i/=2){if((crc & 0x80) != 0){crc *= 2;crc ^= key;}elsecrc *= 2;if((*ptr & i)!=0)crc ^= key;}ptr++;}return(crc);
}
测试函数
#include <iostream>
#include <cstdio>
using namespace std;
unsigned char cal_table_high_first(unsigned char value);
unsigned char CRC8(unsigned char *ptr, unsigned char len,unsigned char key)
{unsigned char i;unsigned char crc=0;while(len--!=0){for(i=0x80; i!=0; i/=2){if((crc & 0x80) != 0){crc *= 2;crc ^= key;}elsecrc *= 2;if((*ptr & i)!=0)crc ^= key;}ptr++;}return(crc);
}
int main(){
//四组数据,前20字节为数据位,21位为CRC校验位
// unsigned char str[] = {0xA8,0xFF,0xFF,0xBE,0x00,0x00,0x01,0x00,0x00,0x76,0x00,0x2A,0x20,0x2A,0x40,0x2A,0x20,0x97,0x02,0x06,0xEA};
// unsigned char st2[] = {0xA8,0xFF,0xFF,0xBE,0x00,0x00,0x09,0x00,0x00,0x7B,0x00,0x2A,0x00,0x2A,0x60,0x2A,0x40,0x9B,0x02,0x07,0xB1};
// unsigned char st3[] = {0xA8,0xFF,0xFF,0x75,0xFF,0xFF,0xDC,0x00,0x00,0x99,0x00,0x2B,0x60,0x2B,0x80,0x2B,0x60,0xAD,0x02,0x07,0x38};
// unsigned char st4[] = {0xA8,0xFF,0xFF,0x7E,0xFF,0xFF,0xF9,0x00,0x00,0x7A,0x00,0x2C,0xC0,0x2C,0xC0,0x2C,0xC0,0xB7,0x02,0x07,0x49};unsigned char ptr = 0x11;printf("0x%x ",cal_table_high_first(0x11));printf("0x%x",CRC8(&ptr,1,0x07));return 0;
} unsigned char cal_table_high_first(unsigned char value)
{unsigned char i, crc;crc = value;/* 数据往左移了8位,需要计算8次 */for (i=8; i>0; --i){ if (crc & 0x80) /* 判断最高位是否为1 */{/* 最高位为1,不需要异或,往左移一位,然后与0x31异或 *//* 0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉 */crc = (crc << 1) ^ 0x07; }else{/* 最高位为0时,不需要异或,整体数据往左移一位 */crc = (crc << 1);}}return crc;
}