想做一个小程序,目的是分析接收下位机的特定寄存器数据然后截取有效数据位,再写入另一个寄存器,下面是程序代码
问题是现在得到的校验数据跟我用其他校验工具得到的不一样,没有查出来是什么问题,请各位高手帮忙检查一下,多谢了//------------------------------确定按钮作用是生成发送前的数据-----------------------
void CCRCbuffDlg::OnOK()
{
// TODO: Add extra validation here
UpdateData(TRUE);
//CString str = m_read;//str为接收来的下位机数据,格式如下行
CString str = "0103000212340000";//试验数据,1234为有效数据 0000为CRC校验位
CString str1;
CString str2;
str1 = substr(str,8,2);
str2 = substr(str,10,2);//取12 和 34
m_buff = str1+" "+str2+" ";
m_b4crc = "01 03 f0 00 "+m_buff ;//crc校验之前的数据格式为 01 03 f0 00 12 34
char data[256] = {0};
int len=Str2Hex(m_b4crc,data);
unsigned char *ptemp=(unsigned char*)((LPCTSTR)data);
unsigned short cc=CreateCRC(ptemp,len);
unsigned short hightbit=cc/256;
unsigned short lowbit = cc-hightbit*256;
/*if (hightbit == 0 && hightbit == 0 && m_strEditRawdata.GetLength() == 0 )
{
m_strEditCRCResult.Empty();
}*/
CString strHighBit;
strHighBit.Format("%02X",hightbit);
CString strLowBit;
strLowBit.Format("%02X",lowbit); CString m_strEditCRCResult;
m_strEditCRCResult = strLowBit +" "+ strHighBit;
if (hightbit == 0 && hightbit == 0 && m_b4crc.GetLength() == 0 )
{
m_strEditCRCResult.Empty();
}
m_send = m_b4crc + m_strEditCRCResult;//发送内容为校验前数据+CRC校验数据
UpdateData(FALSE);
}//以下这段是从网上扒来的CRC校验函数
//---------------------下面为校验码处理函数-----------------------#define CRC16_GEN_POL 0x8005
#define MKSHORT(a,b) ((unsigned short) (a) | ((unsigned short)(b) << 8))
/* ::---------------------------------------------------------------------
:: FN: CreateCRC; CRC in ANSI - C
:: Synopsis: static void CreateCRC(BYTE *CommData,WORD uLen)
:: Function: formation of the CRC16 checksum.
------------------------------------------------------------------------*/
unsigned short CCRCbuffDlg::CreateCRC(unsigned char *CommData, unsigned int uLen)
{
unsigned short uCrc16;
unsigned char abData[2];
uCrc16 = 0;
abData[0] = 0;
while (uLen-- )
{
abData[1] = abData[0];
abData[0] = *CommData++;
if(uCrc16 & 0x8000)
{
uCrc16 = (uCrc16 & 0x7fff) << 1;
uCrc16 ^= CRC16_GEN_POL;
}
else
{
uCrc16 <<= 1;
}
uCrc16 ^= MKSHORT (abData[0] , abData[1]);
}
return(uCrc16);
}
char CCRCbuffDlg::HexChar(char c)
{
if((c>='0')&&(c<='9'))
return c-0x30;
else if((c>='A')&&(c<='F'))
return c-'A'+10;
else if((c>='a')&&(c<='f'))
return c-'a'+10;
else
return 0x10;}int CCRCbuffDlg::Str2Hex(CString str, char *data)
{
int t,t1;
int rlen=0,len=str.GetLength();
//data.SetSize(len/2);
for(int i=0;i<len;)
{
char l,h=str[i];
if(h==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
l=str[i];
t=HexChar(h);
t1=HexChar(l);
if((t==16)||(t1==16))
break;
else
t=t*16+t1;
i++;
data[rlen]=(char)t;
rlen++;
}
return rlen;
}
问题是现在得到的校验数据跟我用其他校验工具得到的不一样,没有查出来是什么问题,请各位高手帮忙检查一下,多谢了//------------------------------确定按钮作用是生成发送前的数据-----------------------
void CCRCbuffDlg::OnOK()
{
// TODO: Add extra validation here
UpdateData(TRUE);
//CString str = m_read;//str为接收来的下位机数据,格式如下行
CString str = "0103000212340000";//试验数据,1234为有效数据 0000为CRC校验位
CString str1;
CString str2;
str1 = substr(str,8,2);
str2 = substr(str,10,2);//取12 和 34
m_buff = str1+" "+str2+" ";
m_b4crc = "01 03 f0 00 "+m_buff ;//crc校验之前的数据格式为 01 03 f0 00 12 34
char data[256] = {0};
int len=Str2Hex(m_b4crc,data);
unsigned char *ptemp=(unsigned char*)((LPCTSTR)data);
unsigned short cc=CreateCRC(ptemp,len);
unsigned short hightbit=cc/256;
unsigned short lowbit = cc-hightbit*256;
/*if (hightbit == 0 && hightbit == 0 && m_strEditRawdata.GetLength() == 0 )
{
m_strEditCRCResult.Empty();
}*/
CString strHighBit;
strHighBit.Format("%02X",hightbit);
CString strLowBit;
strLowBit.Format("%02X",lowbit); CString m_strEditCRCResult;
m_strEditCRCResult = strLowBit +" "+ strHighBit;
if (hightbit == 0 && hightbit == 0 && m_b4crc.GetLength() == 0 )
{
m_strEditCRCResult.Empty();
}
m_send = m_b4crc + m_strEditCRCResult;//发送内容为校验前数据+CRC校验数据
UpdateData(FALSE);
}//以下这段是从网上扒来的CRC校验函数
//---------------------下面为校验码处理函数-----------------------#define CRC16_GEN_POL 0x8005
#define MKSHORT(a,b) ((unsigned short) (a) | ((unsigned short)(b) << 8))
/* ::---------------------------------------------------------------------
:: FN: CreateCRC; CRC in ANSI - C
:: Synopsis: static void CreateCRC(BYTE *CommData,WORD uLen)
:: Function: formation of the CRC16 checksum.
------------------------------------------------------------------------*/
unsigned short CCRCbuffDlg::CreateCRC(unsigned char *CommData, unsigned int uLen)
{
unsigned short uCrc16;
unsigned char abData[2];
uCrc16 = 0;
abData[0] = 0;
while (uLen-- )
{
abData[1] = abData[0];
abData[0] = *CommData++;
if(uCrc16 & 0x8000)
{
uCrc16 = (uCrc16 & 0x7fff) << 1;
uCrc16 ^= CRC16_GEN_POL;
}
else
{
uCrc16 <<= 1;
}
uCrc16 ^= MKSHORT (abData[0] , abData[1]);
}
return(uCrc16);
}
char CCRCbuffDlg::HexChar(char c)
{
if((c>='0')&&(c<='9'))
return c-0x30;
else if((c>='A')&&(c<='F'))
return c-'A'+10;
else if((c>='a')&&(c<='f'))
return c-'a'+10;
else
return 0x10;}int CCRCbuffDlg::Str2Hex(CString str, char *data)
{
int t,t1;
int rlen=0,len=str.GetLength();
//data.SetSize(len/2);
for(int i=0;i<len;)
{
char l,h=str[i];
if(h==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
l=str[i];
t=HexChar(h);
t1=HexChar(l);
if((t==16)||(t1==16))
break;
else
t=t*16+t1;
i++;
data[rlen]=(char)t;
rlen++;
}
return rlen;
}
我不太理解
之前没有接触过CRC校验,多谢啦
我给你一个好使的CRC16表格法
http://my.csdn.net/my/code/detail/16452
速度比循环移位法快多了
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};static const unsigned char aucCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};unsigned short usMBCRC16( unsigned char * pucFrame, unsigned short usLen )
{
unsigned char ucCRCHi = 0xFF;
unsigned char ucCRCLo = 0xFF;
int iIndex; if(usLen > 40)
{
int i = 0 ;
return 0 ;
}
while( usLen-- )
{
iIndex = ucCRCLo ^ *( pucFrame++ );
ucCRCLo = ( unsigned char )( ucCRCHi ^ aucCRCHi[iIndex] );
ucCRCHi = aucCRCLo[iIndex];
}
return ( unsigned short )( ucCRCHi << 8 | ucCRCLo );
}
我应该在函数里面如何调用它
我收到的数据时Cstring m_b4crc = "01 03 f0 00 "+m_buff ;
如何转换成函数里面要求的unsigned char cmd[] = {0x54, 0x03, 0x00, 0x14, 0x00, 0x02};
多谢!
问题也是一样
我应该在函数里面如何调用它
我收到的数据时Cstring m_b4crc = "01 03 f0 00 "+m_buff ;
如何转换成函数里面要求的unsigned char cmd[] = {0x54, 0x03, 0x00, 0x14, 0x00, 0x02};
请赐教!
多谢!