求助,CRC计算错误!百思不得其解啊....

iNemesis 2015-10-15 11:01:05
我做个 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;
...全文
278 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
iNemesis 2015-10-16
  • 打赏
  • 举报
回复
引用 1 楼 UAVGCS 的回复:
单步调一下啊!
调试了,还是这样.......后来确定了是接收到的数据长度有错误
  • 打赏
  • 举报
回复
上面的错了。 正确的如下 #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;
  • 打赏
  • 举报
回复
引用 楼主 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;
看我楼上代码
  • 打赏
  • 举报
回复
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;
}
Pokeeeer 2015-10-16
  • 打赏
  • 举报
回复
单步调一下啊!
iNemesis 2015-10-16
  • 打赏
  • 举报
回复
引用 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的高低位也弄反了

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧