全字节表比半字节表数据精简,比纯计算速度快,实现起来方便,但是在VB6下或是在普通单片机上要变通处理,因为双字节变量处理会溢出而数据失真。
先看一下CSDN上网友XCS101的C程序 CRC-16/MODBUS 算法的三种实现方法_crc16modbus校验计算方法_xcs101的博客-CSDN博客
/* 半字节CRC16(Dow_右移逆序) 0xA001 余式表*/
const unsigned int CRC_16_Tab[16] =
{
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
};
unsigned int ModBusCRC16(unsigned char *data, unsigned char len)
{
unsigned char i,temp;
unsigned int crc_16 = 0xffff;
for(i=0;i>= 4;
crc_16 ^= CRC_16_Tab[temp];
temp = ((unsigned char)(crc_16&0x000F))^(*data>>4);
crc_16 >>= 4;
crc_16 ^= CRC_16_Tab[temp];
}
return crc_16;
}
再基于同数据表的VB6程序表述方法
Private Sub Command4_Click()
'* 半字节CRC16(Dow_右移逆序) 0xA001 余式表*
Dim TestString As String
Dim I As Integer, Temp As Integer
Dim PP As Integer
Dim CRCLo As Byte, CRCHi As Byte, TCRC As Byte
Dim LTable()
LTable() = Array( _
"&H0000", "&HCC01", "&HD801", "&H1400", "&HF001", "&H3C00", "&H2800", "&HE401", _
"&HA001", "&H6C00", "&H7800", "&HB401", "&H5000", "&H9C01", "&H8801", "&H4400")
TestString = Label1.Caption
TestString = "010303E80002"
CRCHi = &HFF: CRCLo = &HFF
For I = 1 To Len(TestString) / 2
PP = Val("&H" + Mid$(TestString, I * 2 - 1, 2))
Temp = (CRCLo And &HF) Xor (PP And &HF)
CRCLo = CRCLo \ 2 ^ 4
TCRC = (CRCHi And &HF)
TCRC = TCRC * 2 ^ 4: CRCLo = CRCLo Or TCRC
CRCHi = CRCHi \ 2 ^ 4
CRCLo = CRCLo Xor (Val("&H" + (Right$(LTable(Temp), 2))))
CRCHi = CRCHi Xor (Val("&H" + (Mid$(LTable(Temp), 3, 2))))
Temp = (CRCLo And &HF) Xor (PP \ 2 ^ 4)
CRCLo = CRCLo \ 2 ^ 4
TCRC = (CRCHi And &HF)
TCRC = TCRC * 2 ^ 4: CRCLo = CRCLo Or TCRC
CRCHi = CRCHi \ 2 ^ 4
CRCLo = CRCLo Xor (Val("&H" + (Right$(LTable(Temp), 2))))
CRCHi = CRCHi Xor (Val("&H" + (Mid$(LTable(Temp), 3, 2))))
Next I
Text1.Text = Hex$(CRCLo) + Hex$(CRCHi)
End Sub
原理是一样的,逻辑也是一样的,除了对字符串字节处理不同外,对CRC16值的处理也不同。在VB6里,C原本Usinged Integer的CRC16值,要改成高低各8位的CRCHi和CRCLo来存储并计算。
关注点:
1、 右移位4位时CRCLo右移4位,CRCHi右移4位到中间变量,然后CRCLo与中间变量或形成新的CRCLo,CRCHi直接右移4位,完成CRCHi和CRCLo的完整移位。
2、与查表中所得进行异或计算时,CRCLo与表项数据的低2位进行异或,CRCHi则与表项数据的高2位异或。
3、左移4位参照右移4位,由中间变量存储临时4位。
经过变换处理,VB6全字节查表计算CRC16就实现了。至此,CRC16纯计算、半字查表和全字节查表在VB6中的实现方法都实现并记录在了笔记。