循環冗餘碼校驗原理
循環冗餘碼校驗英文名稱爲Cyclical Redundancy Check,簡稱CRC。它是利用除法及餘 數的原理來作錯誤偵測(Error Detecting)的。實際應用時,發送裝置計算出CRC值並隨數 據一同發送給接收裝置,接收裝置對收到的數據重新計算CRC並與收到的CRC相比較,若兩個 CRC值不同,則說明數據通訊出現錯誤。
根據應用環境與習慣的不同,CRC又可分爲以下幾種標準:
①CRC-12碼;
②CRC-16碼;
③CRC-CCITT碼;
④CRC-32碼。
CRC-12碼通常用來傳送6-bit字符串。CRC-16及CRC-CCITT碼則用是來傳送8-bit字符,
其中CRC-16爲美國採用,而CRC-CCITT爲歐洲國家所採用。CRC-32碼大都被採用在一種稱爲
Point-to-Point的同步傳輸中。
下面以最常用的CRC-16爲例來說明其生成過程。
CRC-16碼由兩個字節構成,在開始時CRC寄存器的每一位都預置爲1,然後把CRC寄存器
與8-bit的數據進行異或,之後對CRC寄存器從高到低進行移位,在最高位(MSB)的位置補
零,而最低位(LSB,移位後已經被移出CRC寄存器)如果爲1,則把寄存器與預定義的多項
式碼進行異或,否則如果LSB爲零,則無需進行異或。重複上述的由高至低的移位8次,第一
個8-bit數據處理完畢,用此時CRC寄存器的值與下一個8-bit數據異或並進行如前一個數據 似的8次移位。所有的字符處理完成後CRC寄存器內的值即爲最終的CRC值。
下面爲CRC的計算過程:
1.設置CRC寄存器,並給其賦值FFFF(hex)。
2.將數據的第一個8-bit字符與16位CRC寄存器的低8位進行異或,並把結果存入CRC寄 存器。
3.CRC寄存器向右移一位,MSB補零,移出並檢查LSB。
4.如果LSB爲0,重複第三步;若LSB爲1,CRC寄存器與多項式碼相異或。
5.重複第3與第4步直到8次移位全部完成。此時一個8-bit數據處理完畢。
6.重複第2至第5步直到所有數據全部處理完成。
7.最終CRC寄存器的內容即爲CRC值。
將通訊信息幀所有字節按上述步驟計算完成後,最後得到的CRC寄存器的內容即爲CRC校驗碼,將其附着在原通訊信息幀後進行傳輸即可。如果用於Modbus協議設備則還需交換高 低8位,非Modbus協議設備可以不必交換。接收方依同樣方法進行計算,只是計算的內容不 要包括最後兩個字節,然後比較生成的CRC校驗碼和數據幀中的是否相同即可。如果發送方 交換CRC校驗碼的高低8位,則接收方可以計算包括交換後的CRC碼在內的整個數據幀,傳輸 正確的話結果恆爲0x0000。
VB實現:
Public Function funCRC16(data() As Byte, Optional ByVal Offset As Integer = 0, Optional ByVal Length As Integer = 0) As Byte()
Dim CRC16Lo As Byte, CRC16Hi As Byte 'CRC寄存器
Dim CL As Byte, CH As Byte '多項式碼&HA001
Dim SaveHi As Byte, SaveLo As Byte
Dim i As Integer
Dim Flag As Integer
Dim ReturnData(1) As Byte
CRC16Lo = &HFF
CRC16Hi = &HFF
CL = &H1
CH = &HA0
Length = IIf(Length < 1, UBound(data) - Offset, Length - 1)
For i = Offset To Offset + Length
CRC16Lo = CRC16Lo Xor data(i) '每一個數據與CRC寄存器進行異或
For Flag = 0 To 7
SaveHi = CRC16Hi
SaveLo = CRC16Lo
CRC16Hi = CRC16Hi / 2 '高位右移一位
CRC16Lo = CRC16Lo / 2 '低位右移一位
If ((SaveHi And &H1) = &H1) Then '如果高位字節最後一位爲1
CRC16Lo = CRC16Lo Or &H80 '則低位字節右移後前面補1
End If '否則自動補0
If ((SaveLo And &H1) = &H1) Then '如果LSB爲1,則與多項式碼進行異或
CRC16Hi = CRC16Hi Xor CH
CRC16Lo = CRC16Lo Xor CL
End If
Next
Next
ReturnData(0) = CRC16Lo 'CRC低位
ReturnData(1) = CRC16Hi 'CRC高位
funCRC16 = ReturnData
End Function
usage:
Dim ReturnData As Variant
ReturnData = funCRC16(arrDataSend(0) & arrDataSend(1) & arrDataSend(2) & arrDataSend(3) & arrDataSend(4) & arrDataSend(5) & arrDataSend(6))
C代碼:
//***C代碼 CRC16校驗算法***//
unsigned int mb_crc(BYTE *snd,int num)
{
int i,j;
unsigned int c,crc=0xFFFF
for (i=0;i<num;i )
{
c=snd[i] & 0x00FF;
crc^=c;
for(j=0,j<8,j )
{
if (crc & 0x0001)
{
crc>>=1;crc^=0xA001;
}
else crc>>=1
}
}
return(crc);
}