注:genpoly為generator polynomial的合成調(diào),在程序中用作“生成多項(xiàng)式”寄存器。
1.1 直接模2除法CRC實(shí)現(xiàn)方式
對16位的CRC而言,用信息段作被除數(shù),生成多項(xiàng)式(本文1021H,CCITT標(biāo)準(zhǔn))作除數(shù),進(jìn)行模2除法所產(chǎn)生的余數(shù)(2字節(jié))即為CRC校驗(yàn)值,且CRC校驗(yàn)只間余數(shù)而不管商是多少。發(fā)送時(shí)將校驗(yàn)值連在信息段的后面一起發(fā)送。在接收端,接收方只需把接收到的CRC校驗(yàn)值連同信息一,作為新的信息段并對其進(jìn)行相同的CRC運(yùn)算(只比發(fā)送時(shí)多2字節(jié))。若得到的新余數(shù)(校驗(yàn)值)為0,則表明接收到的信息段和CRC都無差錯(cuò);反之,說明信息段或CRC有錯(cuò),應(yīng)做相應(yīng)處理。所以CRC的編碼和譯碼并沒有本質(zhì)的區(qū)別。程序如下:USHORT crc(USHORT data,USHORT genpoly,USHORT accum)
{// data:數(shù)據(jù),所用信息字的第一個(gè)字節(jié);genpoly:CRC多項(xiàng)式,如1021H;accum:累加器的值,第一次賦0,以后放每次校驗(yàn)結(jié)果。
data<<=8; //信息字節(jié)左移到高字節(jié)
for(int i=8;i>0;i--){
if((data^accum)&0x800) //如果(data異或accum)的最高位是1
accum=(accum<<1)^genpoly; //移位與genpoly異域
else accum<<=1; //否則僅移位
data<<=1; //將信息字的下一位升格
}
return accum; //返回用作下一個(gè)信息字校驗(yàn)的累加器值
}
1.2 快速CRC實(shí)現(xiàn)方式
直接模2除法CRC方式雖編程簡單,但效率不高。采用方式方式,要使用16位的多項(xiàng)式及兩字節(jié)的累加器,對每一信息位(bit)累加器都要移位一次,再根據(jù)移位結(jié)果判斷是否作異式;每一字節(jié)重復(fù)8位,運(yùn)算速度相對較慢,不符合計(jì)算機(jī)按比特進(jìn)行計(jì)算的規(guī)律。但如果采用微機(jī)通信中XMODEM協(xié)議所使用的CRC查詢方式,則比直接CRC模2除法方式快4~10倍。查詢方法實(shí)施過程:首先用信息字節(jié)與累加器的高字節(jié)進(jìn)行異或,并將其結(jié)果作初始累加器為0的CRC;然后與原累加器的低字節(jié)再作一次異或。第一步只有256個(gè)樣式,可以構(gòu)造一個(gè)256個(gè)雙字節(jié)的查詢表,一步實(shí)現(xiàn)。這樣對每一字節(jié)只要作兩次操作就可完成。以下是具體步驟。
(1)構(gòu)造查詢表,運(yùn)行直接模2除法CRC函數(shù)CRC(i,1021,0),用I從0~255代入,將結(jié)果按序排列可得到一個(gè)256個(gè)樣式的雙字節(jié)查詢表。該表只作一次,可以先用C語言微型機(jī)上作好,然后再移到單片機(jī)上,留作以后查詢使用。
(2)取一個(gè)雙字節(jié)累加器accum,賦初值0,將信息流的第一個(gè)字節(jié)賦給另一雙字節(jié)變量data(accum和data都是雙字節(jié)變量,以下步驟也是作雙字節(jié)運(yùn)算)。
(3)將accum>>8(也即取原累加器accum的高字節(jié))的值與信息字data相異或,所得結(jié)果(是一個(gè)<256的值)查上述構(gòu)造好的查詢表,得到一個(gè)16位的暫存值。
(4)將accum<<8(即原累加器accum的低字節(jié)左移成高字節(jié),低位補(bǔ)0),與上一步得到的暫存值(16位的值)相異或,結(jié)果作為新的累加器值,賦值給accum。
(5)取信息流的下一字節(jié)賦給data,重復(fù)進(jìn)行第(3)步和第(4)步,直至所有的信息字節(jié)寢用完為止,最后累加器的值就是余數(shù)。
2 擴(kuò)展?jié)h明碼
2.1 編碼方法
CRC校驗(yàn)只能檢錯(cuò)但不能糾錯(cuò)。而1949年提出的漢明碼是一種能糾正單個(gè)錯(cuò)誤的線性分組碼。其中,既是線性分組碼同時(shí)也是循環(huán)碼的(7,4)碼有兩種。其生成矩陣和校驗(yàn)矩陣分列如下:

兩者使用效果等價(jià)。
漢明碼是糾正單個(gè)錯(cuò)誤的完備碼,所有的接收碼都可對應(yīng)到一個(gè)信息(多一對應(yīng)),要么是正確信息,要么是發(fā)生單個(gè)錯(cuò)誤的情形。當(dāng)有兩個(gè)錯(cuò)誤時(shí),會把它當(dāng)成另一個(gè)碼的單個(gè)錯(cuò)誤加以糾正,導(dǎo)致誤碼。
擴(kuò)展?jié)h明碼在此基礎(chǔ)上引入一個(gè)校驗(yàn)和,即在編碼在時(shí)候增加第8位偶校驗(yàn)位,構(gòu)成(8,4)線性分組碼,因而可以糾正一位錯(cuò)誤同時(shí)檢出兩位錯(cuò)誤。事件上,在發(fā)生錯(cuò)誤時(shí)就是這個(gè)偶校驗(yàn)位確定了是錯(cuò)一位還是錯(cuò)兩位。若錯(cuò)一位則可以糾正,錯(cuò)兩位就只能檢出但不能糾正。
編、譯碼均以擴(kuò)展?jié)h明碼(8,4)線性分組碼為例。為了方便單片機(jī)的運(yùn)算,實(shí)現(xiàn)快速編碼,可采用查詢法。因?yàn)樾畔⑹且粋(gè)4位的矢量,記作C,共有16個(gè)可能值。為了構(gòu)成8位發(fā)射碼矢量,可以建立16個(gè)一字節(jié)的查詢作為8位的發(fā)送碼。以生成矩陣G1為例,用信息矢量C乘以成矩陣G1再加上一位偶校驗(yàn)就得到了生成碼(發(fā)送碼)。查詢表為:





