新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > CRC校驗原理與程序設計――(RS485總線系統應用之1

        CRC校驗原理與程序設計――(RS485總線系統應用之1

        作者: 時間:2016-09-12 來源:網絡 收藏

        1.CRC校驗原理

        本文引用地址:http://www.104case.com/article/201609/303590.htm

        1.1 CRC的基本概念:

        CRC是英文Cyclical Redundancy Check的縮寫,翻譯成中文通常稱作循環冗余校驗或簡稱為CRC校驗。它是數據傳輸領域中最常用的一種差錯校驗方法,其特點是傳輸數據和CRC校驗值的長度可以任意選定。在當今手機、計算機和數碼產品普及的信息數字化時代,CRC校驗無處不在。CRC分為多種標準,例如:CRC -12碼通常用來傳送6-bit字符串。CRC-16及CRC-CCITT碼則用是來傳送8-bit字符,其中CRC-16多為美國采用,而CRC- CCITT多為歐洲國家所采用。而CRC-32碼大都被應用在Point-to-Point的同步傳輸中。更多的CRC校驗標準類型參見附表:CRC校驗標準類型。

        1.2的基本原理:

        在代數編碼理論中,一個數值可以表示為一個多項式。例如:一個十進制數值2892,可以用多項式表示為2x3 + 8x2 + 9x + 2(x=10)。同理,一個二進制數值1010101對應的多項式為x6 + x4 + x2 + 1(x=2)。

        生成CRC碼的基本原理是:設被校驗的數據為K位,校驗碼為R位,碼字長度為N(=K+R),則對于CRC碼集中的任一碼字,存在且僅存在一個R次多項式g(x),使得

        V(x)=A(x)g(x)=xRm(x) + r(x);

        其中: m(x)為被校驗數據的K-1次多項式

        r(x)為校驗碼的R-1次多項式

        g(x)稱為生成多項式:g(x)=g0 + g1x1 + g2x2 + ... + g(R-1)x(R-1) + gRxR

        發送方通過指定的g(x)計算出CRC校驗碼,接收方則通過該g(x)來驗證收到的CRC校驗碼。綜上所述,一個完整的CRC校驗過程是:

        發送方:根據要傳送的K位原始數據(二進制碼序列),以標準指定的多項式計算出一個R位校驗碼(CRC碼),附在原始數據后邊,構成一個新的二進制碼序列共K + R位,然后發送出去。

        接收方:將接收到的數據除以與發送方相同的多項式值,如果能夠除盡,則正確,否則證明出錯。還有另外一種處理,就是接收方用發送方相同的方法計算出接收到數據的CRC校驗值,再與發送方發來的校驗值比較,相同則正確,否則證明出錯。

        2.碼的計算步驟:

        例如:有一個要發送的7位二進制數1011001;對應的m(x)=x6 + x4 + x3 + 1。設CRC校驗碼取4位并設g(x)=x4 + x + 1,則該多項式對應的值是10011。根據CRC規則,為保證被除數夠除,首先需將要發送的數擴大2R 即24倍(左移4位),得到 10110010000,對應的xRm(x)=x10 + x8 + x7 + x4 。

        CRC校驗碼的生成本質其實就是采用模2除法取余數,該除法的簡捷計算就是將除數和被除數按位做異或(相同為0,不同為1。0^0=0; 0^1=1; 1^0=1; 1^1=0)運算。需要注意的是,進行異或運算時除數必須和被除數最高有效位對齊。下面是將10110010000除以11001手工計算的演示,得到余數為1010,該值即是數據1011001的CRC校驗值。

        10110010000 將1011001左移4位

        10011 多項式值與被除數最高有效位對齊

        =00101010000 第1次異或結果

        10011 多項式值與被除數最高有效位對齊

        =00001100000 第2次異或結果

        10011 多項式值與被除數最高有效位對齊

        =00000101100 第3次異或結果

        10011 多項式值與被除數最高有效位對齊

        =00000001010 第4次異或結果

        為了簡便計算機程序求解CRC,在實際應用中通常把多項式值的最高位舍掉,并且將參加計算的數據高低位顛倒后再計算。前面的演算數據顛倒后的運算情況如下:

        00001001101

        11001

        00001010100

        11001

        00000110000

        11001

        00110100000

        11001

        01010000000

        提請注意:只有真正讀懂以上手工演算的步驟和規律,才能理解下節內容。

        3.的程序設計

        下面以最常用的CRC-16-IBM校驗標準為例來說明CRC校驗碼的生成過程。 因為CRC-16碼由兩個字節構成,所以首先要準備一個16位的CRC寄存器,并將每一位都置1。具體的計算步驟為:

        ① 設置CRC寄存器,并給其賦值FFFFH。

        ② 將被校驗數據的第一個字節(8Bit)與CRC寄存器的低8位進行異或,結果存CRC寄存器。

        ③ CRC寄存器的值向右移一位,最高位(MSB)補零,檢查移出的最低位(LSB)是否為1。

        ④ 如果LSB為0,重復第三步;若LSB為1,CRC寄存器與CRC16多項式值A001H相異或。

        ⑤ 重復第③與第④步,直到該字節的8次移位全部完成。

        ⑥ 如果被校驗數據有多個字節,則重復第②至第⑤步直到所有數據全部處理完。

        ⑦ 最終CRC寄存器的內容即為CRC值。

        3.1 用查表法求CRC函數的程序

        查表法省去了將被校驗數據移位并與多項式異或計算的步驟,因此比計算法更快捷,但程序編碼量偏大。

        3.1.1 用VC編寫的程序

        unsigned short CRC16(puchMsg, usDataLen)

        unsigned char * puchMsg ;

        unsigned short usDataLen ;

        {

        unsigned char uchCRCHi = 0xFF ;

        unsigned char uchCRCLo = 0xFF ;

        unsigned uIndex ;

        while (usDataLen--)

        {

        uIndex = uchCRCLo ^ * puchMsg++ ;

        uchCRCLo = uchCRCHi ^ auchCRCLo [uIndex] ;

        uchCRCHi = auchCRCHi [uIndex] ;

        }

        return (uchCRCLo 8 | uchCRCHi) ;

        }

        static char auchCRCHi[] = {

        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,


        上一頁 1 2 3 4 下一頁

        關鍵詞: CRC校驗 RS485總線

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 新泰市| 炎陵县| 建湖县| 阿合奇县| 丰宁| 尼玛县| 台前县| 灵武市| 湖口县| 盐亭县| 安义县| 贵溪市| 日照市| 高陵县| 鄂温| 屏东县| 盐池县| 伽师县| 秀山| 册亨县| 西平县| 太和县| 法库县| 北川| 铜川市| 定远县| 兴业县| 余姚市| 鹿泉市| 林周县| 福州市| 治多县| 莒南县| 留坝县| 石家庄市| 玉溪市| 巴林右旗| 台前县| 灌阳县| 弥渡县| 蒙自县|