user-0 提问: 求助,CRC计算错误！百思不得其解啊....

回复:
user: user-0
content: 引用 1 楼 UAVGCS 的回复:单步调一下啊！ 调试了，还是这样.......后来确定了是接收到的数据长度有错误

user: user-1
content: 上面的错了。 正确的如下 #include <stdio.h> #include <stdlib.h> #include <windows.h> WORD GetCheckCode(const char * pSendBuf, int nEnd) { 	WORD wCrc = WORD(0xFFFF); 	for(int i=0; i<nEnd; i++)	 	{ 		 		wCrc ^= WORD(BYTE(pSendBuf[i])); 		for(int j=0; j<8; j++)		 		{ 			if(wCrc & 1)		 			{	 				wCrc >>= 1; 		 				wCrc ^= 0xA001; 	 			} 			else	 			{ 				wCrc >>= 1;  			}	 		}	 	} 	return wCrc; } void main() { 	BYTE szSend[8] = {0}; 	szSend[0] = 0x01; 	szSend[1] = 0x03; 	szSend[2] = 0x00; 	szSend[3] = 0x02; 	szSend[4] = 0x00; 	szSend[5] = 0x01;	 	WORD CRCCode = GetCheckCode((char*)szSend,6);	 	BYTE Code[2] = {0}; 	memcpy(Code,&CRCCode,sizeof(Code)); 	memcpy(&szSend[6],Code,sizeof(Code)); }  引用 楼主 zhk_xbox 的回复:我做个 modbus的东西 需要CRC校验码 然后不知道为什么都计算错误 比如设备手册上给的0x01,0x03,0x00,0x02,0x00,0x01计算出来的CRC是0x25,0xca(0x25ca) 我这边计算的变成了c79a，代码如下：   unsigned int  u16CRC_Reg = 0xffff;  for(int iDataLenght = 0; iDataLenght < 8; iDataLenght++)   {     //Step2:把数据帧中的第一个字节(开始)的8位与CRC寄存器     //      中的低字节进行异或运算,结果存回CRC寄存器     u16CRC_Reg = u16CRC_Reg ^ u8InData[iDataLenght];      u16CRC_Temp = 0x0000;      //Step3:将CRC寄存器向右移一位，最高位填以0,最低位移出并检测     //Step4:如果最低位为0,重复第3步(下一次移位);     //      如果最低位为1,将CRC寄存器与一个预设的固定值(0A001H)进行异或运算     for(int iByte =  0; iByte < 8; iByte++)     {       if(u16CRC_Reg & 0x0001)       {         u16CRC_Reg = (u16CRC_Reg >> 1) ^ CRC_Mul;       }       else         u16CRC_Reg = u16CRC_Reg >> 1;     }   }    cout<<hex<<u16CRC_Reg<<endl;

user: user-1
content: 引用 楼主 zhk_xbox 的回复:我做个 modbus的东西 需要CRC校验码 然后不知道为什么都计算错误 比如设备手册上给的0x01,0x03,0x00,0x02,0x00,0x01计算出来的CRC是0x25,0xca(0x25ca) 我这边计算的变成了c79a，代码如下：   unsigned int  u16CRC_Reg = 0xffff;  for(int iDataLenght = 0; iDataLenght < 8; iDataLenght++)   {     //Step2:把数据帧中的第一个字节(开始)的8位与CRC寄存器     //      中的低字节进行异或运算,结果存回CRC寄存器     u16CRC_Reg = u16CRC_Reg ^ u8InData[iDataLenght];      u16CRC_Temp = 0x0000;      //Step3:将CRC寄存器向右移一位，最高位填以0,最低位移出并检测     //Step4:如果最低位为0,重复第3步(下一次移位);     //      如果最低位为1,将CRC寄存器与一个预设的固定值(0A001H)进行异或运算     for(int iByte =  0; iByte < 8; iByte++)     {       if(u16CRC_Reg & 0x0001)       {         u16CRC_Reg = (u16CRC_Reg >> 1) ^ CRC_Mul;       }       else         u16CRC_Reg = u16CRC_Reg >> 1;     }   }    cout<<hex<<u16CRC_Reg<<endl;  看我楼上代码

user: user-1
content: GetCRC(const char * buf,int len) { 	unsigned short crc; 	int i,j; 	short tc; 	crc = 0xffff; 	byte sbit;	 	if (len != 0) 	{		 		for(i = 0;i < len;i++) 		{	 			tc = (short)(crc>>8); 			crc = (tc^buf[i])&0x00FF; 			for(j = 0;j < 8;j++) 			{ 				sbit = (char)(crc & 0x01); 	 				crc >>= 1;				 				if (sbit != 0)  					crc = (crc ^ 0xA001) & 0x0000FFFF;  			} 		} 	} 	return crc; }

user: user-2
content: 单步调一下啊！

user: user-0
content: 引用 4 楼 爷就是这个范儿的回复:上面的错了。 正确的如下 #include <stdio.h> #include <stdlib.h> #include <windows.h> WORD GetCheckCode(const char * pSendBuf, int nEnd) { 	WORD wCrc = WORD(0xFFFF); 	for(int i=0; i<nEnd; i++)	 	{ 		 		wCrc ^= WORD(BYTE(pSendBuf[i])); 		for(int j=0; j<8; j++)		 		{ 			if(wCrc & 1)		 			{	 				wCrc >>= 1; 		 				wCrc ^= 0xA001; 	 			} 			else	 			{ 				wCrc >>= 1;  			}	 		}	 	} 	return wCrc; } void main() { 	BYTE szSend[8] = {0}; 	szSend[0] = 0x01; 	szSend[1] = 0x03; 	szSend[2] = 0x00; 	szSend[3] = 0x02; 	szSend[4] = 0x00; 	szSend[5] = 0x01;	 	WORD CRCCode = GetCheckCode((char*)szSend,6);	 	BYTE Code[2] = {0}; 	memcpy(Code,&CRCCode,sizeof(Code)); 	memcpy(&szSend[6],Code,sizeof(Code)); }  [quote=引用 楼主 zhk_xbox 的回复:] 我做个 modbus的东西 需要CRC校验码 然后不知道为什么都计算错误 比如设备手册上给的0x01,0x03,0x00,0x02,0x00,0x01计算出来的CRC是0x25,0xca(0x25ca) 我这边计算的变成了c79a，代码如下：   unsigned int  u16CRC_Reg = 0xffff;  for(int iDataLenght = 0; iDataLenght < 8; iDataLenght++)   {     //Step2:把数据帧中的第一个字节(开始)的8位与CRC寄存器     //      中的低字节进行异或运算,结果存回CRC寄存器     u16CRC_Reg = u16CRC_Reg ^ u8InData[iDataLenght];      u16CRC_Temp = 0x0000;      //Step3:将CRC寄存器向右移一位，最高位填以0,最低位移出并检测     //Step4:如果最低位为0,重复第3步(下一次移位);     //      如果最低位为1,将CRC寄存器与一个预设的固定值(0A001H)进行异或运算     for(int iByte =  0; iByte < 8; iByte++)     {       if(u16CRC_Reg & 0x0001)       {         u16CRC_Reg = (u16CRC_Reg >> 1) ^ CRC_Mul;       }       else         u16CRC_Reg = u16CRC_Reg >> 1;     }   }    cout<<hex<<u16CRC_Reg<<endl; [/quote] 多谢 多谢 正常了 因为发送数据包的设备有问题 发送的数据长度不正常 而且我这边也把CRC的高低位也弄反了