CRC校验算法在嵌入式开发中有着很广泛的应用。以下是来源于网络的CRC算法,转载仅用于个人学习使用,如有侵权,请联系删除。
CRC校验核心原理
CRC(Cyclic Redundancy Check)通过对数据多项式进行模2除法,生成固定位数的校验码。
以下是实现中的五个关键参数:
(1)Poly:生成多项式(决定校验强度)
(2)Init:初始寄存器值
(3)Refin:输入字节位反转
(4)Refout:输出结果位反转
(5)Xorout:最终异或掩码
以下仅选取2例开发中应用到的CRC算法,如有其他需求,请点击上述链接查看。
1、CRC-8 (x⁸+x²+x+1)
应用:基础通信协议
参数:Poly=0x07, Init=0x00, Refin=false, Refout=false, Xorout=0x00
/**
* @brief 标准CRC8校验(x⁸ + x² + x + 1)
* @param data 数据指针
* @param length 数据长度
* @return CRC8值
* @note
* - 多项式: 0x07
* - 初始值: 0x00
*/
uint8_t crc8(uint8_t *data, uint16_t length)
{
uint8_t crc = 0;
while(length--)
{
crc ^= *data++;
for(int i=0; i<8; i++)
{
crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : (crc << 1);
}
}
return crc;
}
2、CRC-16/MODBUS (x¹⁶+x¹⁵+x²+1)
应用:工业控制器
参数:Poly=0x8005, Init=0xFFFF, Refin=true, Refout=true, Xorout=0x0000
/**
* @brief CRC-16/MODBUS校验(x¹⁶ + x¹⁵ + x² + 1)
* @param data 数据指针
* @param length 数据长度
* @return CRC16值
* @note
* - 初始值: 0xFFFF
* - 输出异或值: 0x0000
* - 典型应用: Modbus RTU协议
* @example
* uint8_t frame[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01};
* uint16_t crc = crc16_modbus(frame, 6); // 应返回0x840A
*/
uint16_t crc16_modbus(uint8_t *data, uint16_t length)
{
uint16_t crc = 0xFFFF;
while(length--)
{
crc ^= *data++;
for(int i=0; i<8; i++)
{
if(crc & 1) crc = (crc >> 1) ^ 0xA001;
else crc >>= 1;
}
}
return crc;
}