循環冗餘碼校驗原理及VB實現

循環冗餘碼校驗原理
  循環冗餘碼校驗英文名稱爲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);
}

發佈了10 篇原創文章 · 獲贊 14 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章