如何生成给定数据中第23位的CRC值?多种校验方法尝试未果
校验值计算匹配问题求助
我需要生成传入数据中第23位的校验值,但尝试使用CRC-8、LRC、BCC及校验和方法计算后,结果均与目标值不符,不清楚需添加或修改什么逻辑才能得到正确的校验值,附上测试代码寻求帮助。
#include <stdio.h> unsigned char a[19][22] = { {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad (checksum value) {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, //b2 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, //e1 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, //d3 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, //da {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, //d0 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x21}, //d5 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x49,0x21,0x33,0x00,0x11,0x00,0x48,0x03,0x21}, //d7 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x51,0x21,0x43,0x00,0x11,0x00,0x48,0x03,0x21}, //d1 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d6 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x20,0x48,0x03,0x31}, //d7 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x52,0x21,0x63,0x00,0x11,0x00,0x48,0x03,0x31}, //d5 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x30,0x48,0x03,0x21}, //d7 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x20,0x48,0x03,0x21}, //d6 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x53,0x21,0x53,0x00,0x11,0x00,0x48,0x03,0x21} //d4 }; unsigned char calculate_byte_sum(unsigned char *data, int length) { unsigned char checksum = 0; int i; for (i = 0; i< length; i++) { checksum += data[i]; } return checksum; } unsigned char calculate_crc8(unsigned char *data, int length) { unsigned char crc = 0x00; unsigned char polynomial = 0x07; for (int i = 0; i < length; i++) { crc += data[i]; for (int j = 0; j < 8; j++) { if (crc & 0x80) { crc = (crc << 1) ^ polynomial; } else { crc <<= 1; } } } return crc; } unsigned char calculate_bcc(unsigned char *data, int length) { unsigned char bcc = 0; for (int i = 0; i < length; i++) { bcc ^= data[i]; } return bcc; } unsigned char calculate_lrc(unsigned char *data, int length) { unsigned char lrc = 0; for (int i = 0; i < length; i++) { lrc += data[i]; } return (unsigned char)((~lrc)); } void fcs_test(unsigned char* data, unsigned int len) { unsigned char ch,ch1, ch2,ch3,ch4,ch5; ch = calculate_byte_sum(data, len); ch1 = calculate_crc8(data, len); ch2 = calculate_bcc(data,len); ch3= calculate_lrc(data,len); printf("calculate_byte_sum = %02x calculate_crc8 = %02x calculate_bcc = %02x calculate_lrc = %02x\n", ch,ch1,ch2,ch3); // printf("fcs = %02x \n", ch); } int main() { unsigned int i; for (i=0 ; i < 19; i++) { fcs_test(&a[i][0], 22); } return 0; }
问题排查与修正方案
1. 核心错误:校验范围错误
你当前代码是对全部22个字节计算校验值,但目标校验位是第23位,说明校验值应该基于前21个字节计算,数组的第22位是已经给出的目标校验值,不能包含在计算范围内。
2. CRC-8实现逻辑错误
标准CRC-8的计算是将当前数据字节与CRC寄存器异或,而非相加。你的代码中crc += data[i];是错误的,正确逻辑应改为异或操作。
3. LRC实现不完整
标准LRC通常要求取反后加1(即补码形式),而非单纯取反,部分通信协议会明确要求这一步。
修正后的代码示例
#include <stdio.h> unsigned char a[19][22] = { {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad (checksum value) {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, //ad {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x04}, //b2 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x19,0x53,0x00,0x11,0x20,0x45,0x02,0x91}, //e1 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x29,0x20,0x43,0x00,0x11,0x20,0x46,0x03,0x01}, //d3 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x38,0x20,0x83,0x00,0x11,0x20,0x47,0x03,0x21}, //da {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x43,0x21,0x13,0x00,0x11,0x20,0x47,0x03,0x21}, //d0 {0x02,0x01,0x05,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x47,0x21,0x23,0x00,0x11,0x20,0x47,0x03,0x2
相关产品推荐
相关产品推荐

