CRC16校验
CRC校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能。
可以对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
CRC校验中有两个关键点,一是预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式),可以随机选择,也可以使用国际标准。
CRC16校验是一种常规的算法,常用于通讯数据的校验,有多种计算因子,本文代码在STM32F103上测试正确。供分享。
代码
入口参数:一串需要校验的数据(十六进制)及数据长度
输出:CRC16计算结果:16位
unsigned int CRC16func(unsigned char array_of_databytes[], unsigned char number_of_databytes)
{
unsigned int current_crc_value;
unsigned char hi,lo;
int i, j;
current_crc_value = PRESET_VALUE; //本处#define PRESET_VALUE 0xFFFF
for (i = 0; i < number_of_databytes; i++)
{
current_crc_value = current_crc_value ^ ((unsigned int)array_of_databytes[i]);
for (j = 0; j < 8; j++)
{
if (current_crc_value & 0x0001)
{
current_crc_value = (current_crc_value >> 1) ^ POLYNOMIAL; //本处#define POLYNOMIAL 0xA001 还有其他如0x8408 // x^16 + x^12 + x^5 + 1
}
else
{
current_crc_value = (current_crc_value >> 1);
}
}
}
//有的校验方法,要求对结果取反,有,不需要,视情况而定
//current_crc_value = ~current_crc_value;
//调换一下高低位,有的算法需要调换一下,有的不需要 hi= (current_crc_value>>8)&0xff;
lo = current_crc_value &0xff;
current_crc_value = ((lo<<8) | hi);
return current_crc_value;
}
补充说明
CRC校验一定要搞清楚采用什么校验规则,否则结果就会出错。网上资料较多,此处不赘述。本文(本函数)只是其中按一个规则编制的,也可在网上在线测试一下计算结果,如http://www.ip33.com/crc.html,输入同样的数据串,来对比一下和函数的计算结果是否一致,本文代码经实践可行。
据本人经验,结果不一致时,问题多出在有时RCR结果需要取反,或是高低位调换,此时需要把CRC16结果写成二进制来分析一下。