CRC8校验分析
***************************************************
更多精彩,歡迎進(jìn)入:http://shop115376623.taobao.com
***************************************************
CRC即循環(huán)冗余校驗(yàn)碼(Cyclic Redundancy Check):是數(shù)據(jù)通信領(lǐng)域中最常用的一種差錯(cuò)校驗(yàn)碼,其特征是信息字段和校驗(yàn)字段的長(zhǎng)度可以任意選定。
?????CRC校驗(yàn)可以簡(jiǎn)單地描述為:例如我們要發(fā)送一些數(shù)據(jù)(信息字段),為了避免一些干擾以及在接收端的對(duì)讀取的數(shù)據(jù)進(jìn)行判斷是否接受的是真實(shí)的數(shù)據(jù),這時(shí)我們就要加上校驗(yàn)數(shù)據(jù)(即CRC校驗(yàn)碼),來(lái)判斷接收的數(shù)據(jù)是否正確。
在發(fā)送端,根據(jù)要傳送的k位二進(jìn)制碼序列,以一定的規(guī)則(CRC校驗(yàn)有不同的規(guī)則。這個(gè)規(guī)則,在差錯(cuò)控制理論中稱為“生成多項(xiàng)式”。)產(chǎn)生一個(gè)校驗(yàn)用的r位校驗(yàn)碼(CRC碼),附在原始信息后邊,構(gòu)成一個(gè)新的二進(jìn)制碼序列數(shù)共k+r位,然后發(fā)送出去。
在接收端,根據(jù)信息碼和CRC碼之間所遵循的規(guī)則(即與發(fā)送時(shí)生成CRC校驗(yàn)碼相同的規(guī)則)進(jìn)行檢驗(yàn),校驗(yàn)采用計(jì)算機(jī)的模二除法,即除數(shù)和被除數(shù)(即生成多項(xiàng)式)做異或運(yùn)算,進(jìn)行異或運(yùn)算時(shí)除數(shù)和被除數(shù)最高位對(duì)齊,進(jìn)行按位異或運(yùn)算,若最終的數(shù)據(jù)能被除盡,則傳輸正確;否則,傳輸錯(cuò)誤。
?????CRC8即最終生成的CRC校驗(yàn)碼為1字節(jié),其生成多項(xiàng)式,生成多項(xiàng)式為g(x)=x8+x5+x4+1,相當(dāng)于g(x)=1·x8+0·x7+0·x6+1·x5+1·x4+0·x3+0·x2+0·x1+1·x0,即對(duì)應(yīng)的二進(jìn)制數(shù)為100110001。
?????CRC8校驗(yàn)算法:
?????1.CRC8校驗(yàn)的一般性算法:
??????? 例如:? 信息字段代碼為:?00000001 00000010?????????————??? 對(duì)應(yīng)m(x)=x8+x
?????????????????? 生成多項(xiàng)式為:g(x)=x8+x5+x4+1?????????????????————??? 對(duì)應(yīng)g(x)的二進(jìn)制代碼為:100110001
?????? ?現(xiàn)在我們將要對(duì)2字節(jié)數(shù)據(jù)0x0102生成CRC8校驗(yàn)碼,并最終將生成的1字節(jié)CRC校驗(yàn)碼跟在0x0102的后面,即 0x01 02 ##,(##即8為CRC碼),最終生成的3字節(jié)數(shù)據(jù)就是經(jīng)CRC8校驗(yàn)生成的數(shù)據(jù)。
??????? 先計(jì)算x8m(x)=x16+x9,對(duì)應(yīng)的2進(jìn)制數(shù)為:100000010 00000000??。可以看到這樣運(yùn)算所得到的結(jié)果其實(shí)就是將信息字段代碼的數(shù)左移8位。因?yàn)樽罱K要將生成的8位CRC8校驗(yàn)碼附在信息字段的后面,所以要將信息字段的數(shù)左移8位。最后用x8m(x)得到的二進(jìn)制數(shù)對(duì)生成多項(xiàng)式g(x)進(jìn)行模二運(yùn)算,最終的余數(shù)(其二進(jìn)制數(shù)的位數(shù)一定比生成多項(xiàng)式g(x)的位數(shù)小)就是所要的CRC8校驗(yàn)碼。
???????100000010 00000000
????^ 100110001?
? ---------------------------
???????000110011 00000000
????^????? 100110 001
? ---------------------------
????????????010101? 00100000
???? ^????????? 10011 0001
? ---------------------------
????????????? 00110 00110000
??? ^???????????100 110001
??---------------------------
?????????????????010?11110100
??? ^????????????10?0110001
??---------------------------
?????????????????? 00 10010110
???????對(duì)x8m(x)做模二運(yùn)算取余得10010110(0x96),這個(gè)8位的二進(jìn)制數(shù)就是CRC8校驗(yàn)碼。所以,經(jīng)CRC8校驗(yàn)后研發(fā)送的數(shù)據(jù)就是0x010296。??????????????
????2.CRC8校驗(yàn)在DS18B20中的應(yīng)用:
????? 以上分析的是常規(guī)的CRC8校驗(yàn)方法。在DS18B20中,有兩處用到CRC。一是DS18B20的8字節(jié)的序列號(hào),最后一字節(jié)是前面七個(gè)字節(jié)的CRC碼,這是為了保證序列號(hào)的唯一性與正確性;另一個(gè)是在DS18B20內(nèi)部9字節(jié)的高速溫度存儲(chǔ)器,其第9字節(jié)是前面8個(gè)字節(jié)的CRC校驗(yàn)碼,這是為了溫度數(shù)據(jù)傳輸?shù)恼_性。而在DS18B20中生成CRC碼所用到的方法不同于常規(guī)生成算法,它采用的是逆序CRC信息單元編碼算法,該CRC的生成是由DS18B20中的多項(xiàng)式寄存器通過(guò)其中所包含的移位寄存器以及異或門(mén)對(duì)輸入該多項(xiàng)式寄存器的每一位二進(jìn)制數(shù)做一定的運(yùn)算所得到的CRC碼(可以查看Maxim官網(wǎng)上DS18B20的應(yīng)用筆記Note27,專門(mén)介紹DS18B20CRC詳細(xì)生成過(guò)程)。在此列舉兩種DS18B20CRC校驗(yàn)的C程序。
??????A.按位運(yùn)算方法
[cpp]?view plaincopy??????B.查表法
????????unsigned char crc_array[256] = {
??????????????????????????????????????????????????? 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,?
??????????????????????????????????????????????????? 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,?
????????????????????????????????????????????????????0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,?
??????????????????????????????????????????????????? 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,?
????????????????????????????????????????????????????0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,?
??????????????????????????????????????????????????? 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,?
????????????????????????????????????????????????????0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,?
??????????????????????????????????????????????????? 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,?
??????????????????????????????????????????????????? 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,?
????????????????????????????????????????????????????0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,?
??????????????????????????????????????????????????? 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,?
?????????????????????????????????????????????????? ?0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,?
??????????????????????????????????????????????????? 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,?
????????????????????????????????????????????????????0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,?
????????????????????????????????????????????????????0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,?
??????????????????????????????????????????????????? 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,?
????????????????????????????????????????????????????0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,?
????????????????????????????????????????????????????0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,?
??????????????????????????????????????????????????? 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,?
??????????????????????????????????????????????????? 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,?
????????????????????????????????????????????????????0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,?
????????????????????????????????????????????????????0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,?
????????????????????????????????????????????????????0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,?
????????????????????????????????????????????????????0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,?
????????????????????????????????????????????????????0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,?
??????????????????????????????????????????????????? 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,?
??????????????????????????????????????????????????? 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,?
??????????????????????????????????????????????????? 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,?
????????????????????????????????????????????????????0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,?
????????????????????????????????????????????????????0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,?
????????????????????????????????????????????????????0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,?
??????????????????????????????????????????????????? 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,?
??????????????????????????????????????????????????? };
??????????? unsigned char CRC8_Table(unsigned char *p, char counter)
??????????? {
?????????????? unsigned char crc8 = 0;
????????????? ?for( ; counter > 0; counter--)
??????????????? {
?????????????? ??? crc8 = CRC8Table[crc8^*p]; //查表得到CRC碼
????????????????? ?p++;
??????????????? }
????????????? return crc8;
????????????}
???????DS18B20的兩種校驗(yàn)CRC碼的方法本質(zhì)上都是一樣的。查表法是對(duì)0x00~0xff這256個(gè)數(shù)依次生成與每一個(gè)數(shù)對(duì)應(yīng)的CRC碼所組合成的表,每次算一字節(jié)數(shù)據(jù)的CRC碼不用經(jīng)過(guò)calcrc_1byte(uchar abyte)這個(gè)函數(shù)對(duì)每個(gè)數(shù)據(jù)的最低位進(jìn)行判斷是1還是0,而直接通過(guò)查表的方式直接提取出??crc8^*p的CRC碼,其運(yùn)行效率相對(duì)按位運(yùn)算方法更高,但是查表法所列的表卻很占空間。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
- 上一篇: 用 Python 可视化分析全球火山分布
- 下一篇: ACWing 893. 集合-Nim游戏