日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

CRC8校验分析

發(fā)布時(shí)間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CRC8校验分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

***************************************************

更多精彩,歡迎進(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
  • /********************************************************/??
  • /*DS18B20的CRC8校驗(yàn)程序*/??
  • /********************************************************/???
  • uchar?calcrc_1byte(uchar?abyte)????
  • {????
  • ???uchar?i,crc_1byte;?????
  • ???crc_1byte=0;????????????????//設(shè)定crc_1byte初值為0??
  • ???for(i?=?0;?i?<?8;?i++)????
  • ????{????
  • ??????if(((crc_1byte^abyte)&0x01))????
  • ?????????{????
  • ???????????crc_1byte^=0x18;?????
  • ???????????crc_1byte>>=1;????
  • ???????????crc_1byte|=0x80;????
  • ??????????}??????????
  • ???????else?????
  • ??????????crc_1byte>>=1;???
  • ???????abyte>>=1;??????????
  • ?????}???
  • ?????return?crc_1byte;???
  • }???
  • uchar?calcrc_bytes(uchar?*p,uchar?len)??
  • {??
  • ?uchar?crc=0;??
  • ?while(len--)?//len為總共要校驗(yàn)的字節(jié)數(shù)??
  • ??{??
  • ????crc=calcrc_1byte(crc^*p++);??
  • ??}??
  • ?return?crc;??//若最終返回的crc為0,則數(shù)據(jù)傳輸正確??
  • }??
  • ??????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é)

    以上是生活随笔為你收集整理的CRC8校验分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。