CRC计算方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算 CRC-16 循环冗余校验码的程序开发 ing CRC-16 Cyclic Redundancy Check Code Program Development of Calculat alculating
【内容摘要】CRC-16 是检测数据在发送过程中发生错误的常用校验方法,本文通过从工程应用的角 度,讲述如何实现 CRC-16 的程序开发,并给出了 Visual Basic 和 Visual C++程序代码,给从事工业控 制的人员在写通信程序的时候提供一些有价值的参考。 一、前言 CRC 的计算方式是将欲传输的数据块视为一堆连续位所构成的整个数值, 将此数值除以一个特定 的除数, 通常以二进制表示, 此除数称为生成多项式 (ANSI CRC-16 的生成多项式为: x16 + x15 + x2 + 1)。目前较常用的 CRC 位数目有 8 和 16 以及 32,在这里只讲述如何写 CRC 位数目为 16 的程序。 CRC 位数目越大,数据的错误检测率则越高,但必须多花一些时间进行数据的计算。 二、CRC-16 计算步骤 CRC-16 的计算方法有两种:查表法与计算法,在这里只讲述计算法。本人在 2000 年在江西亚东水泥 公司上班时,在某电力仪表上的说明书中摘录下来的计算 CRC-16 步骤如下: 1、 Load a 16-bit register with FFFF hex. Call this the CRC register. 2、 Exclusive OR the first 8-bit byte of the message with the low-order byte of the 16-bit CRC, putting the result in the CRC register. 3、 Shift the CRC register one bit to the right (toward the LSB), zero-filling the MSB. Extract and Examine. 4、 If the LSB was 1: Exclusive OR the CRC register with polynomial value A001 hex. If the LSB was 0: Repeat step 3 (another shift). 5、 Repeat step 3 and 4 until 8 shifts have been performed. When this is done, a complete 8-bit byte will have been processed. 6、 Repeat step 2 through 5 for the next 8-bit byte of them message. 7、 The final content of the CRC register is the CRC value. 中文解释如下: 1、定义一个初始值为 FFFF 的 16 位的变量,该变量称为 CRC 寄存器。(想想在程序中,应该怎 么表示 16 位的变量呢?) 2、把欲发送或接收消息的高 8 位和 CRC 寄存器的底 8 位作异或运算,并把结果在赋到 CRC 寄 存器。 3、CRC 寄存器右移 1 位 (朝最低位) , 同时最高位添零。 取出并检查最低位是否为 1。 ( Visual Basi c 里如何做移位的运算呢?) 4、 如果为 1,则 CRC 寄存器与多项式 A001 异或; 如果为 0, 则重复第 3 步的动作。 (Visual Basic 里如何判断一个字节里某个位的值呢?) 5、重复 3 和 4 直到完成了 8 次移位。这样完整的 8 位字节将完成处理了。 6、对于下一个 8 位字节的处理就是重复第 2 步到第 5 步了 7、把所有的欲发送或接收消息这样处理后, CRC 寄存器里的值就是我们最终需要得到的 CRC 校验码。 如果你能正确回答我的问题,那么恭喜你,你自己可以用 Visual Basic 写数据采集卡的控制程序 了。
CString str; str.Format(" %02X %02X",(BYTE)(CRC>>8),(BYTE)CRC); AfxMessageBox(str); CDialog::OnOK(); } WORD CCRC_16Dlg::ANSI_CRC_16(BYTE* btData,int nLength) //ANSI CRC-16,x16 + x15 + x2 + 1 { CHECKVALUE(btData,nLength); WORD CRC=0xFFFF; BYTE j,Tmp=0; int i; for(i=0;i<nLength;i++) { CRC^=btData[i]; for (j=0;j<8;j++) { Tmp=CRC&0x0001; CRC=CRC>>1; if(Tmp)CRC=(CRC^0xA001); } } return ((CRC>>8)+(CRC<<8)); /* 应用时高在先 */ } int CCRC_16Dlg::StrToHex(CString str, BYTE *btData) { int nLength=str.GetLength(); if(nLength<2) return 0; for(int i=0;i<nLength;i+=3) _stscanf(str.Mid(i,2),"%02X",&btData[i/3]); return (i+1)/3; }
End Sub 三、Visual C++程序实现
程序界面 主要代码:
#define CHECKVALUE(pt,nl) 1;} BOOL CCRC_16Dlg::OnInitDialog() { …… m_strCRC="01 04 00 5C 00 04"; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CCRC_16Dlg::OnOK() { UpdateData(TRUE); CString strTemp; strTemp=m_strCRC; WORD CRC; BYTE btData[4096]; int nLength=StrToHex(strTemp,btData); CRC=ANSI_CRC_16(btData,nLength); //ANSI-16 if((btData==NULL)||(nLength<=0)){AfxMessageBox("无效数组!&
相关文档
最新文档