0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

了解和使用Maxim 1-Wire和iButton產(chǎn)品的循環(huán)冗余校驗

星星科技指導(dǎo)員 ? 來源:ADI ? 作者:ADI ? 2023-05-16 11:23 ? 次閱讀

所有1-Wire器件(包括iButton器件)在只讀存儲器(ROM)中包含一個8字節(jié)的唯一注冊號。該注冊號用作1-Wire總線上的唯一網(wǎng)絡(luò)地址。為確保數(shù)據(jù)通信的完整性,每個注冊號的一個字節(jié)為1-Wire CRC字節(jié)。本應(yīng)用筆記解釋了如何計算這種8位1-Wire CRC。它還繼續(xù)解釋用于驗證保存在設(shè)備內(nèi)存中的記錄的 16 位 CRC。1-Wire CRC和CRC-16均在選定的1-Wire器件的硬件中生成,以驗證數(shù)據(jù)。??

介紹

Maxim iButton產(chǎn)品是一系列器件,它們都按照稱為1-Wire協(xié)議的特定命令序列通過單線進行通信。每個器件的一個關(guān)鍵特性是在制造時寫入每個部件的唯一 8 字節(jié) ROM 代碼。此 8 字節(jié)代碼的組件如圖 1 所示。最低有效字節(jié)包含標識 iButton 產(chǎn)品類型的系列代碼。例如,DS1990A的家族代碼為01十六進制,DS1922L的家族代碼為41十六進制。由于相同或不同系列類型的多個器件可以同時駐留在同一條1-Wire總線上,因此主機必須確定如何正確訪問其位于1-Wire總線上的每個器件。家庭代碼提供了此信息。接下來的 6 個字節(jié)包含一個唯一的序列號,允許將同一系列代碼中的多個設(shè)備相互區(qū)分。這個唯一的序列號可以看作是1-Wire總線上每個器件的“地址”。整個設(shè)備集合加上主機,形成了一種微型局域網(wǎng)或MicroLAN;它們都通過單根公共線路進行通信。每個器件的ROM代碼中的最高有效字節(jié)包含一個循環(huán)冗余校驗(CRC)值,該值基于該部分的前7個字節(jié)的數(shù)據(jù)。當主機系統(tǒng)開始與設(shè)備通信時,首先讀取 8 字節(jié) ROM,首先讀取 LSB。如果主機計算的CRC與ROM數(shù)據(jù)第7字節(jié)中包含的CRC一致,則可以認為通信有效。如果不是這種情況,則發(fā)生了錯誤,應(yīng)再次讀取ROM代碼。

wKgaomRi9yuAeXv6AAA7RAFf83c175.gif

圖1.iButton系統(tǒng)配置使用1-Wire CRC。

一些iButton產(chǎn)品除了具有主機系統(tǒng)可以使用適當命令訪問的8字節(jié)ROM之外,還具有高達8kB的隨機存取存儲器(RAM)。即使iButton設(shè)備沒有板載CRC硬件,如果主機能夠計算ROM代碼的CRC值,那么也可以開發(fā)使用CRC在設(shè)備的RAM部分存儲和檢索數(shù)據(jù)的程序。數(shù)據(jù)可以正常方式寫入設(shè)備;然后,主機計算的CRC值將附加并與數(shù)據(jù)一起存儲。當從iButton設(shè)備檢索此數(shù)據(jù)時,該過程將反轉(zhuǎn)。主機將為數(shù)據(jù)字節(jié)計算的 CRC 值與作為該數(shù)據(jù)的 CRC 存儲在內(nèi)存中的值進行比較。如果值相等,則從iButton設(shè)備讀取的數(shù)據(jù)可以被視為有效。為了利用CRC的強大功能來驗證1-Wire總線上的串行通信,必須了解CRC是什么以及它們是如何工作的。此外,硬件或軟件實現(xiàn)都需要一種由主機計算CRC值的實用方法。

背景

可以通過多種方式檢查串行數(shù)據(jù)是否存在錯誤。一種常見的方法是在每個正在檢查的數(shù)據(jù)包中包含額外的位,以指示是否發(fā)生了錯誤。例如,對于 8 位 ASCII 字符的數(shù)據(jù)包,每個 ASCII 字符都會附加一個額外的位,指示該字符是否包含錯誤。假設(shè)數(shù)據(jù)由 11010001 位字符串組成。一 9千位將被附加,因此 1 的總位數(shù)始終是奇數(shù)。因此,將附加一個 1,數(shù)據(jù)包將變?yōu)?11010001。帶下劃線的字符表示使完整的 9 位數(shù)據(jù)包具有奇數(shù)位數(shù)所需的奇偶校驗位值。如果接收到的數(shù)據(jù)是111010001的,則假定該信息是正確的。但是,如果收到的數(shù)據(jù)是111010101,其中 7千左邊的位被錯誤地接收,1 的總數(shù)不再奇數(shù),并且檢測到錯誤條件并采取適當?shù)拇胧_@種類型的方案稱為奇偶校驗。同樣,也可以選擇1的總數(shù)始終等于偶數(shù),因此稱為偶數(shù)奇偶校驗。但是,此方案僅限于檢測奇數(shù)位錯誤。在上面的示例中,如果數(shù)據(jù)損壞并變得111011101,其中 6千和 7千左邊的位是錯誤的,奇偶校驗看起來是正確的;然而,無論使用偶數(shù)奇偶校驗還是奇偶校驗,都不會檢測到錯誤。

描述

馬克西姆1線CRC

在以最少的硬件量定位串行數(shù)據(jù)流中的錯誤時,最有效的錯誤檢測方案是CRC。本文介紹了Maxim產(chǎn)品中使用的CRC函數(shù)的操作和性質(zhì),而不涉及證明語句和描述的數(shù)學細節(jié)。CRC屬性背后的數(shù)學概念在參考文獻中有詳細的描述。CRC最容易理解的是考慮該功能,因為它實際上是內(nèi)置在硬件中的,通常表示為帶有反饋的移位寄存器排列,如圖2所示?;蛘?,CRC 有時被稱為虛擬變量 X 中的多項式表達式,每個項都有二進制系數(shù)。系數(shù)直接對應(yīng)于移位寄存器實現(xiàn)中顯示的反饋路徑。硬件描述的移位寄存器中的級數(shù)或多項式表達式中存在的最高階系數(shù)表示計算的 CRC 值的大小。數(shù)字數(shù)據(jù)通信中常用的CRC代碼包括CRC-16和CRC-CCITT,每個代碼都計算16位CRC值。Maxim 1-Wire CRC幅度為8位,用于檢查寫入每個64-Wire產(chǎn)品的1位ROM代碼。該ROM代碼由寫入最低有效字節(jié)的8位家族代碼,寫入接下來48個字節(jié)的唯一6位序列號以及基于ROM的前56位計算然后寫入最高有效字節(jié)的CRC值組成。圖2中由異或門表示的反饋路徑的位置,或多項式表達式中系數(shù)的存在,決定了CRC的屬性以及算法定位數(shù)據(jù)中某些類型錯誤的能力。對于1-Wire CRC,可檢測的錯誤類型包括:

64 位數(shù)字內(nèi)任意位置的任何奇數(shù)錯誤。

64 位數(shù)字內(nèi)的任何位置的所有雙位錯誤。

可以包含在 8 位“窗口”中的任何錯誤集群(1-8 位不正確)。

大多數(shù)較大的錯誤群集。

輸入數(shù)據(jù)與圖2中移位寄存器第八級的輸出是非或的。移位寄存器在數(shù)學上可以視為分頻電路。輸入數(shù)據(jù)是除數(shù),帶有反饋的移位寄存器充當除數(shù)。結(jié)果商被丟棄,其余部分是該特定輸入數(shù)據(jù)流的CRC值,該值在最后一個數(shù)據(jù)位移入后駐留在移位寄存器中。從移位寄存器實現(xiàn)中可以明顯看出,最終結(jié)果(CRC值)以一種非常復(fù)雜的方式依賴于所呈現(xiàn)位的過去歷史。因此,需要極其罕見的錯誤組合才能逃脫這種方法的檢測。

wKgZomRi9yyANun2AAAZtuDKZ5Q491.gif

圖2.馬克西姆 1 線 8 位 CRC。

示例2中的示例在顯示每個數(shù)據(jù)位后計算CRC值。移位寄存器電路在計算開始時始終復(fù)位為0。計算從 64 位 ROM 的 LSB 開始,這是本例中的 02 十六進制系列代碼。輸入所有56個數(shù)據(jù)位(序列號+族碼)后,移位寄存器中包含的值為A2十六進制,即該輸入流的1-Wire CRC值。如果已經(jīng)計算出的CRC值(在本例中為A2十六進制)現(xiàn)在用作接下來8位數(shù)據(jù)的移位寄存器的輸入,則輸入整個64位數(shù)據(jù)后移位寄存器中的最終結(jié)果應(yīng)全部為0。對于1-Wire CRC算法,此屬性始終成立。如果移位寄存器中出現(xiàn)的任何 8 位值也用作輸入流中的下一個 8 位,則移位寄存器中出現(xiàn)的結(jié)果在 8千數(shù)據(jù)位已移入始終為 00 十六進制。這可以通過觀察8千移位寄存器的級始終等于輸入數(shù)據(jù)位,使得控制反饋的EXOR門的輸出和移位寄存器第一級的下一個狀態(tài)值始終等于邏輯0。這導(dǎo)致移位寄存器在每個數(shù)據(jù)位顯示時簡單地從左向右偏移 0,直到整個寄存器在 0 之后用 8 填充千位。Maxim 1-Wire 64位ROM的結(jié)構(gòu)利用這一特性來簡化用于讀取ROM的器件的硬件設(shè)計。清除主機中的移位寄存器,然后讀取64個ROM位,包括CRC值。如果發(fā)生了正確的讀數(shù),則移位寄存器再次全為0,這是一個容易檢測到的情況。如果移位寄存器中保留非零值,則必須重復(fù)讀取操作。

到目前為止,討論主要圍繞CRC工藝的硬件表示,但顯然,與硬件方法并行的軟件解決方案是計算1-Wire CRC值的另一種方法。示例 1 中給出了如何對過程進行編碼的示例。請注意,具有常數(shù)18十六進制的A寄存器的XRL(異或)是由于在第四級和第五級之后1-Wire CRC中存在EXOR反饋門,如圖2所示。另一種軟件解決方案是簡單地構(gòu)建一個查找表,該查找表可以直接訪問當前存儲在CRC寄存器中的任何8位值和任何8位模式的新數(shù)據(jù)。對于CRC寄存器的當前值為00十六進制的簡單情況,可以計算輸入字節(jié)的256個不同位組合并將其存儲在矩陣中,其中矩陣的索引等于輸入字節(jié)的值(即索引為I = 0到255)??梢宰C明,如果CRC寄存器的當前值不是00十六進制,那么對于任何當前CRC值和任何輸入字節(jié),查找表值與簡化情況相同,但索引到表中的計算采用以下形式:

新CRC = 表 [I] 表示 I = 0 至 255;
其中 I = (當前 CRC) EXOR (輸入字節(jié))

對于當前CRC寄存器值為00十六進制的情況,公式簡化為簡單情況。第二種方法可以減少計算時間,因為操作可以基于字節(jié)完成,而不是前面示例中面向位的命令。但是,存在內(nèi)存容量權(quán)衡,因為查找表必須存儲并消耗 256 字節(jié),而第一個示例除了程序代碼之外幾乎沒有存儲。示例 3 顯示了此類代碼的示例。表 1 顯示了使用查找表方法重復(fù)的前面的示例。1-Wire CRC的兩個特性有助于調(diào)試用于計算CRC值的代碼。對于硬件實現(xiàn),已經(jīng)提到了第一個屬性。如果將CRC寄存器的當前值用作數(shù)據(jù)的下一個字節(jié),則生成的CRC值始終為00十六進制(請參閱上面的解釋)??捎糜诖_認代碼正確操作的第二個屬性是輸入 CRC 寄存器當前值的 1 補碼。對于1-Wire CRC算法,得到的CRC值始終為35十六進制或53十進制。其原因可以通過觀察輸入1的補碼數(shù)據(jù)時CRC寄存器的操作來解釋,如表2所示。

例 1.匯編語言程序

DO_CRC:	PUSH ACC	;save accumulator
	PUSH B	;save the B register
	PUSH ACC	;save bits to be shifted
	MOV B,#8	;set shift = 8 bits ;

CRC_LOOP:	XRL A,CRC	;calculate CRC
	RRC A	;move it to the carry
	MOV A,CRC	;get the last CRC value
	JNC ZERO	;skip if data = 0
	XRL A,#18H	;update the CRC value
;
ZERO:	RRC A	;position the new CRC
	MOV CRC,A	;store the new CRC
	POP ACC	;get the remaining bits
	RR A	;position the next bit
	PUSH ACC	;save the remaining bits
	DJNZ B,CRC_LOOP	;repeat for eight bits
	POP ACC	;clean up the stack
	POP B	;restore the B register
	POP ACC	;restore the accumulator
	RET

例 2.1-Wire CRC的計算示例

wKgaomRi_VCAACC7AAA0_7IpFO0831.png

CRC價值 輸入值
00000000 0
00000000 1
10001100 0 2
01000110 0___
00100011 0
10011101 0
11000010 0 0
01100001 0___
10111100 0
01011110 0
00101111 1 字節(jié)
00010111 1___
00001011 1
00000101 0
10001110 0 1
01000111 0___
10101111 0
11011011 0
11100001 0 8
11111100 1___
11110010 1
11110101 1
01111010 0 字節(jié)
00111101 1___
00011110 1
10000011 0
11001101 0 1
11101010 0___
01110101 0
10110110 0
01011011 0 0
10100001 0___
11011100 0
01101110 0
00110111 0 0
10010111 0___
11000111 0
11101111 0
11111011 0 0
11110001 0___
11110100 0
01111010 0
00111101 0 0
10010010 0___
01001001 0
10101000 0
01010100 0 0
00101010 0___
00010101 0
10000110 0
01000111 0 0
10101101 0___
11011010 0
01101101 0
10111010 0 0
01011101 0___
10100010 = A2 十六進制 = [00000001B81C (序列號) + 02(家庭代碼)] 的 CRC 值]
10100010 0
01010001 1
00101000 0 2
00010100 0___
00001010 0
00000101 1
00000010 0 ?
00000001 1___
00000000 = 00 十六進制 = A2 的 CRC 值 [(CRC) + 00000001B81C(序列號)+ 02(家庭代碼)]

例 3.1線CRC查找功能


Var
	CRC : Byte;
Procedure Do_CRC(X: Byte);
{
	This procedure calculates the cumulative Maxim 1-Wire CRC of all bytes passed to it.
The result accumulates in the global variable CRC.
}
Const
	Table : Array[0..255] of Byte = (

	0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
	157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
	35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
	190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
	70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
	219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
	101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
	248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
	140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
	17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
	175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
	50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
	202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
	87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
	233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
	116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53);

Begin
	CRC := Table[CRC xor X];
End;
當前 CRC 值 (= 當前表索引) 輸入數(shù)據(jù) 新指數(shù)(= 當前 CRC 異或輸入數(shù)據(jù)) 表 (新索引) (= 新的 CRC 值)
0000 0000 = 00 十六進制 0000 0010 = 02 十六進制 (00 H xor 02 H) = 02 十六進制 = 2 十進制 表[2]= 1011 1100 = BC 十六進制 = 188 dec
1011 1100 = BC 十六進制 0001 1100 = 1C 十六進制 (BC H xor 1C H) = A0 十六進制 = 160 dec 表[160]= 1010 1111 = AF 十六進制 = 175 dec
1010 1111 = 自動對焦六角 1011 1000 = B8 十六進制 (自動對焦 H xor B8 H) = 17 十六進制 = 23 十進制 表[23]= 0001 1110 = 1E 十六進制 = 30 dec
0001 1110 = 1E 十六進制 0000 0001 = 01 十六進制 (1E H xor 01 H) = 1 F 十六進制 = 31 dec 表[31]= 1101 110 = 直流十六進制 = 220 dec
1101 1100 = 直流十六進制 0000 0000 = 00 十六進制 (直流高或 00 小時)= 直流十六進制 = 220 十進制 表[220]= 1111 0100 = F4 十六進制 = 244 dec
11110100 = F4 十六進制 0000 0000 = 00 十六進制 (F4 H xor 00 H) = F4 十六進制 = 244 dec 表 [244]= 0001 0101 = 15 十六進制 = 21 十進制
0001 0101 = 15 十六進制 0000 0000 = 00 十六進制 (15 H xor 00 H) = 15 十六進制 = 21 十進制 表[21]= 1010 0010 = A2 十六進制 = 162 dec
1010 0010 = A2 十六進制 10100010 = A2 十六進制 (A2 H xor A2 H) = 十六進制 = 0 十進制 表[0]=0000 0000 = 00 十六進制 = 0 十進制

CRC寄存器與1的CRC寄存器補充相結(jié)合

X0 X1 X2 X3 X4 X5 X6 X7 X7*
1 X0 X1 X2 X3* X4* X5 X6 X6*
1 1 X0 X1 X2* X3 X4* X5 X5*
1 1 1 X0 X1* X2* X3 X4* X4*
0 1 1 1 X0* X1* X2 X3 X3*
1 0 1 1 0 X0* X1* X2 X2*
1 1 0 1 0 1 X0* X1* X1*
0 1 1 0 1 0 1 X0* X0*
0 0 1 1 0 1 0 1 最終 CRC 值 = 35 十六進制,53 十進制
注:X我* = X 的補碼我

CRC-16 計算 iButton 設(shè)備中的 RAM 記錄

如介紹中所述,除了在所有iButton設(shè)備中找到的唯一8字節(jié)ROM代碼外,某些iButton設(shè)備還具有RAM。由于RAM中存儲的數(shù)據(jù)量可能比8字節(jié)ROM碼大,Maxim建議使用16位CRC值來保證數(shù)據(jù)的完整性,而不是用于ROM的8位1-Wire CRC。建議的特定CRC通常稱為CRC-16。移位寄存器和多項式表示如圖3所示。該圖顯示,對于 16 位 CRC,移位寄存器包含 16 個階段,多項式表達式具有 16 階項。如前所述,iButton設(shè)備不計算CRC值。主機必須生成該值,然后將 16 位 CRC 值追加到實際數(shù)據(jù)的末尾。由于iButton設(shè)備的“通信通道”(即兩個金屬接觸面)的不確定性,數(shù)據(jù)傳輸可能會遇到通常分為三類的錯誤。首先,短暫的間歇性連接會導(dǎo)致數(shù)據(jù)中出現(xiàn)少量位錯誤,正常的CRC-<>函數(shù)旨在檢測這些錯誤。第二種類型的錯誤發(fā)生在完全失去聯(lián)系時,例如當iButton設(shè)備從閱讀器上移開時。

這會導(dǎo)致數(shù)據(jù)的最后一部分被讀取為邏輯 1,因為主機不會將任何與 iButton 設(shè)備的連接解釋為所有 1。在大多數(shù)情況下,正常的CRC-16功能也可以檢測到這種情況。第三種類型的錯誤是由讀卡器短路引起的,這可能是由iButton設(shè)備未正確插入或在讀卡器中明顯傾斜引起的。讀取器短路會導(dǎo)致主機將數(shù)據(jù)讀取為全部 0。使用 CRC 時,這可能會導(dǎo)致問題,因為確定數(shù)據(jù)有效性的方法是讀取數(shù)據(jù)加上存儲的 CRC 值,并查看在主機上計算的結(jié)果 CRC 是否為 0000 十六進制(對于 16 位 CRC)。如果讀取器短路,則數(shù)據(jù)加上與數(shù)據(jù)一起存儲的CRC值將讀取為全為0,并且發(fā)生了錯誤讀取,但主機計算的CRC錯誤地指示了有效的讀取。為避免這種情況,Maxim建議將計算出的CRC-16值(CRC-16*)的補碼與寫入RAM的數(shù)據(jù)一起存儲。使用未互補的CRC-16值,從iButton器件檢索數(shù)據(jù)的過程與1-Wire CRC外殼類似。也就是說,如果主機中的CRC寄存器初始化為0000十六進制,然后從iButton設(shè)備讀取所有數(shù)據(jù)加上與數(shù)據(jù)一起存儲的CRC-16值,則主機的計算結(jié)果應(yīng)具有0000十六進制,作為最終結(jié)果。相反,如果CRC-16值的補碼與iButton中的數(shù)據(jù)一起存儲,則主機上的CRC寄存器初始化為0000十六進制,并讀取實際數(shù)據(jù)加上存儲的CRC-16*值。生成的 CRC 值應(yīng)為 B001 十六進制才能有效讀取。這極大地改善了系統(tǒng)的操作,因為它不能再被閱讀器的短路所愚弄。CRC-16功能具有這些特性的原因可以用類似于1-Wire CRC外殼的方式顯示出來(見圖3和圖5)。16 位 CRC 的操作在理論上與前面描述的 8 位版本相同,但 CRC 的屬性發(fā)生了變化,因為 16 位值現(xiàn)在可用于錯誤檢測。對于CRC-16功能,可檢測的錯誤類型包括:

數(shù)據(jù)記錄中任何位置的任何奇數(shù)錯誤。

數(shù)據(jù)記錄中任意位置的所有雙位錯誤。

可能包含在 16 位“窗口”內(nèi)的任何錯誤簇(1-16 位不正確)。

大多數(shù)較大的錯誤群集。

chaijie_default.png

圖3.CRC-16 硬件描述和多項式。

CRC-16 功能的硬件實現(xiàn)從圖 3 中給出的描述中很簡單。示例 4 顯示了一個軟件解決方案,該解決方案類似于使用單位操作計算 CRC-16 值的硬件操作。和以前一樣,可以通過使用查找表開發(fā)計算量較少的軟件解決方案。8位1-Wire CRC查找表的基本概念也適用于CRC-16外殼。但是,需要對 8 位情況的過程進行輕微修改,因為如果像以前一樣將 CRC-16 函數(shù)的整個 16 位結(jié)果映射到一個表中,則該表將有 2 個16或 65,536 個條目。示例 5 顯示了另一種方法,其中計算 16 位 CRC 值并將其存儲在兩個 256 個條目表中,一個包含高位字節(jié),另一個包含生成的 CRC 的低位字節(jié)。對于任何當前的 16 位 CRC 值(表示為當前高階字節(jié)的Current_CRC16_Hi和當前低階字節(jié)的Current_CRC16_Lo)以及任何新的輸入字節(jié),確定索引到高階字節(jié)表中以定位新的高階字節(jié) CRC 值 (New_CRC16_Hi) 的公式如下:

New_CRC16_Hi = CRC16_Tabhi[I] 表示 I = 0 到 255;其中 I = (Current_CRC16_Lo) EXOR(輸入字節(jié))

確定索引的公式 進入低位字節(jié)表,用于定位新的低位字節(jié) CRC 值 (New_CRC16_Lo) 表示為:

New_CRC16_Lo = (CRC16_Tablo[I]) EXOR (Current_CRC16_Hi) 對于 I = 0 到 255;
其中 I = (Current_CRC16_Lo) EXOR(輸入字節(jié))

圖 4 顯示了此方法工作原理的示例。

例 4.用于CRC-16計算的匯編語言

crc_lo data 20h ; lo byte of crc calculation (bit addressable)
crc_hi data 21h ; hi part of crc calculation



;---------------------------------------------------------------------------
;	CRC16 subroutine.
;	- accumulator is assumed to have byte to be crc'ed
;	- two direct variables are used crc_hi and crc_lo
;	- crc_hi and crc_lo contain the CRC16 result
;---------------------------------------------------------------------------
crc16:			; calculate crc with accumulator
	push b	; save value of b
	mov b, #08h	; number of bits to crc.
crc_get_bit:
	rrc a	; get low order bit into carry
	push acc	; save a for later use
	jc crc_in_1	;got a 1 input to crc
	mov c, crc_lo.0	;xor with a 0 input bit is bit
	sjmp crc_cont	;continue
crc_in_1:
	mov c, crc_lo.0	;xor with a 1 input bit
	cpl c	;is not bit.
crc_cont:
	jnc crc_shift	; if carry set, just shift
	cpl crc_hi.6	;complement bit 15 of crc
	cpl crc_lo.1	;complement bit 2 of crc
crc_shift
	mov a, crc_hi	; carry is in appropriate setting
	rrc a ; rotate	it
	mov crc_hi, a	; and save it
	mov a, crc_lo	; again, carry is okay
	rrc a ; rotate	it
	mov crc_lo, a	; and save it
	pop acc	; get acc back
	djnz b, crc_get_bit	; go get the next bit
	pop b	; restore b
	ret
	end

例 5.使用查找表的CRC-16匯編語言

crc_lo data 40h	; any direct address is okay
crc_hi data 41h
tmp data 42h



;---------------------------------------------------------------------------
;	CRC16 subroutine.
;	- accumulator is assumed to have byte to be crc'ed
;	- three direct variables are used, tmp, crc_hi and crc_lo
;	- crc_hi and crc_lo contain the CRC16 result
;	- this CRC16 algorithm uses a table lookup
;---------------------------------------------------------------------------
crc16:
	xrl a, crc_lo	; create index into tables
	mov tmp, a	; save index
	push dph	; save dptr
	push dpl	;
	mov dptr, #crc16_tablo	; low part of table address
	movc a, @a+dptr	; get low byte
	xrl a, crc_hi	;
	mov crc_lo, a	; save of low result
	mov dptr, #crc16_tabhi	; high part of table address
	mov a, tmp	; index
	movc a, @a+dptr	;
	mov crc_hi, a	; save high result
	pop dpl	; restore pointer
	pop dph	;
	ret	; all done with calculation
crc16_tablo:
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 000h, 0c1h, 081h, 040h, 001h, 0c0h, 080h, 041h
	db 001h, 0c0h, 080h, 041h, 000h, 0c1h, 081h, 040h
crc16_tabhi:
	db 000h, 0c0h, 0c1h, 001h, 0c3h, 003h, 002h, 0c2h
	db 0c6h, 006h, 007h, 0c7h, 005h, 0c5h, 0c4h, 004h
	db 0cch, 00ch, 00dh, 0cdh, 00fh, 0cfh, 0ceh, 00eh
	db 00ah, 0cah, 0cbh, 00bh, 0c9h, 009h, 008h, 0c8h
	db 0d8h, 018h, 019h, 0d9h, 01bh, 0dbh, 0dah, 01ah
	db 01eh, 0deh, 0dfh, 01fh, 0ddh, 01dh, 01ch, 0dch
	db 014h, 0d4h, 0d5h, 015h, 0d7h, 017h, 016h, 0d6h
	db 0d2h, 012h, 013h, 0d3h, 011h, 0d1h, 0d0h, 010h
	db 0f0h, 030h, 031h, 0f1h, 033h, 0f3h, 0f2h, 032h
	db 036h, 0f6h, 0f7h, 037h, 0f5h, 035h, 034h, 0f4h
	db 03ch, 0fch, 0fdh, 03dh, 0ffh, 03fh, 03eh, 0feh
	db 0fah, 03ah, 03bh, 0fbh, 039h, 0f9h, 0f8h, 038h
	db 028h, 0e8h, 0e9h, 029h, 0ebh, 02bh, 02ah, 0eah
	db 0eeh, 02eh, 02fh, 0efh, 02dh, 0edh, 0ech, 02ch
	db 0e4h, 024h, 025h, 0e5h, 027h, 0e7h, 0e6h, 026h
	db 022h, 0e2h, 0e3h, 023h, 0e1h, 021h, 020h, 0e0h
	db 0a0h, 060h, 061h, 0a1h, 063h, 0a3h, 0a2h, 062h
	db 066h, 0a6h, 0a7h, 067h, 0a5h, 065h, 064h, 0a4h
	db 06ch, 0ach, 0adh, 06dh, 0afh, 06fh, 06eh, 0aeh
	db 0aah, 06ah, 06bh, 0abh, 069h, 0a9h, 0a8h, 068h
	db 078h, 0b8h, 0b9h, 079h, 0bbh, 07bh, 07ah, 0bah
	db 0beh, 07eh, 07fh, 0bfh, 07dh, 0bdh, 0bch, 07ch
	db 0b4h, 074h, 075h, 0b5h, 077h, 0b7h, 0b6h, 076h
	db 072h, 0b2h, 0b3h, 073h, 0b1h, 071h, 070h, 0b0h
	db 050h, 090h, 091h, 051h, 093h, 053h, 052h, 092h
	db 096h, 056h, 057h, 097h, 055h, 095h, 094h, 054h
	db 09ch, 05ch, 05dh, 09dh, 05fh, 09fh, 09eh, 05eh
	db 05ah, 09ah, 09bh, 05bh, 099h, 059h, 058h, 098h
	db 088h, 048h, 049h, 089h, 04bh, 08bh, 08ah, 04ah
	db 04eh, 08eh, 08fh, 04fh, 08dh, 04dh, 04ch, 08ch
	db 044h, 084h, 085h, 045h, 087h, 047h, 046h, 086h
	db 082h, 042h, 043h, 083h, 041h, 081h, 080h, 040h

wKgaomRi9zCARtbWAAA7_IBErRY724.gif

圖4.CRC-16的計算和表查找方法的比較。

實施例6給出了一種有趣的中間方法。該代碼使用圖 16 所示的公式對整個當前 CRC 值和輸入字節(jié)進行操作,從而為每個輸入的字節(jié)生成一個 CRC-5 值。還顯示了方程的推導(dǎo),使用字母字符表示當前的 16 位 CRC 值,使用數(shù)字字符表示傳入字節(jié)的位。八班后的結(jié)果得出所示方程。然后,這些方程可用于預(yù)先計算新CRC值的大部分。例如,請注意,數(shù)量ABCDEFGH01234567(定義為所有這些位的EXOR)是當前CRC的傳入數(shù)據(jù)字節(jié)和低位字節(jié)的奇偶校驗。與上述逐位方法和查找表方法相比,此方法減少了計算時間和內(nèi)存空間。最后,提到了可用作測試用例的 CRC-16 函數(shù)的兩個屬性,以幫助調(diào)試任何先前方法的代碼。第一個特性與1-Wire CRC外殼相同。如果CRC寄存器的當前16位內(nèi)容也用作接下來的16位輸入,則生成的CRC值始終為0000十六進制。CRC-16函數(shù)的第二個特性也類似于1-Wire CRC情況,如果CRC寄存器當前1位內(nèi)容的16補碼也用作下一個16位輸入,則得到的CRC值始終為B0 01十六進制。這兩個CRC-16特性的證明與1-Wire CRC外殼的證明類似。

例 6.高速CRC-16計算的匯編語言程序

lo equ 40h ; low byte of CRC
hi equ 41h ; high byte of CRC



crc16:
	push acc	; save the accumulator.
	xrl a, lo
	mov lo, hi	; move the high byte of the CRC.
	mov hi, a	; save data xor low(crc) for later
	mov c, p
	jnc crc0
	xrl lo, #01h	; add the parity to CRC bit 0
crc0:
	rrc a	; get the low bit in c
	jnc crc1
	xrl lo, #40h	; need to fix bit 6 of the result
crc1:
	mov c, acc.7
	xrl a, hi	; compute the results for other bits.
	rrc a	; shift them into place
	mov hi, a	; and save them
	jnc crc2
	xrl lo, #80h	; now clean up bit 7
crc2:
	pop acc	; restore everything and return
	ret

wKgZomRi9zGAdGnPAACz2SJ5lbE695.gif

圖5.高速CRC-16計算方法。

審核比較:郭婷


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5343

    瀏覽量

    120348
  • 存儲器
    +關(guān)注

    關(guān)注

    38

    文章

    7492

    瀏覽量

    163828
  • 1-Wir
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    5847
收藏 人收藏

    評論

    相關(guān)推薦

    1-Wire 總線讀寫器

    Maxim Dallas 1-Wire 專用讀寫器DS9097/DS9490 淘寶網(wǎng){:23:}
    發(fā)表于 07-10 14:30

    1-Wire 編程器

    `可對DALLAS 1-Wire器件進行編程,無論是DS18B20,還是EPROM 還是EEPROM,還是IButton紐扣等等。。兼容Maxim軟件,采用USB接口,完全替代DS9097以及DS9097E25。`
    發(fā)表于 07-10 15:05

    如何訪問1-Wire API

    任何組件在創(chuàng)建者來實現(xiàn)這一點。有人知道如何訪問1-Wire API嗎?謝謝 以上來自于百度翻譯 以下為原文I have been looking for a 1-wire component
    發(fā)表于 07-29 15:25

    用XML實現(xiàn)1-Wire標簽

    Dallas Semiconductor 所有1-Wire®器件以及iButton®產(chǎn)品在出廠前都被指定了各自唯一的64 位1-Wire 網(wǎng)絡(luò)地址值這個地址值光刻在每片
    發(fā)表于 04-17 12:03 ?25次下載

    1-wire單總線的基本原理

    1-wire單總線的基本原理 1-wire 單總線是Maxim 全資子公司Dallas 的一項專有技術(shù)與目前多數(shù)標準串行數(shù)據(jù)通信方式如SPI/I2C/MICROWIRE
    發(fā)表于 02-05 17:58 ?79次下載

    1-Wire 串行存儲器產(chǎn)品

    1-Wire®串行存儲器產(chǎn)品通過單線連接為你的產(chǎn)品添加存儲器! 1-Wire串行存儲器產(chǎn)品提供EEPROM和EPROM存儲矩陣,能
    發(fā)表于 04-20 23:22 ?1524次閱讀
    <b class='flag-5'>1-Wire</b> 串行存儲器<b class='flag-5'>產(chǎn)品</b>

    1-Wire搜索算法

    摘要:Maxim1-Wire®器件都帶有一個64位的唯一注冊碼,存儲在只讀存儲器內(nèi)(ROM),能夠在1-Wire網(wǎng)絡(luò)中通過1-Wire主機對其尋址。如果
    發(fā)表于 04-30 14:09 ?1385次閱讀
    <b class='flag-5'>1-Wire</b>搜索算法

    理解和運用Maxim iButton產(chǎn)品中的循環(huán)冗余校驗

    摘要:全部1-Wire®器件,包括iButton®器件,都具有唯一的8字節(jié)注冊碼,儲存在只讀存儲器(ROM)中。該注冊碼在1-Wire總線上用作唯一的網(wǎng)絡(luò)地址。為確保數(shù)據(jù)通信的完整性,每個注
    發(fā)表于 04-30 14:20 ?1076次閱讀
    理解和運用<b class='flag-5'>Maxim</b> <b class='flag-5'>iButton</b><b class='flag-5'>產(chǎn)品</b>中的<b class='flag-5'>循環(huán)</b><b class='flag-5'>冗余</b><b class='flag-5'>校驗</b>

    1-Wire器件與8051系列單片機的軟件接口

    摘 要:分析了1-Wire總線的硬件結(jié)構(gòu)和通信協(xié)議,結(jié)合實際應(yīng)用設(shè)計了1-Wire器件與8051系列單片機的軟件接口。 關(guān)鍵詞:1-Wire總線,軟件接口,CRC校驗  
    發(fā)表于 05-17 12:40 ?2043次閱讀
    <b class='flag-5'>1-Wire</b>器件與8051系列單片機的軟件接口

    Bluetooth to 1-Wire communicat

    how to enable communication between a Bluetooth® serial and Maxim® 1-Wire adapters. Topics discussed are: selectin
    發(fā)表于 02-27 17:29 ?1298次閱讀
    Bluetooth to <b class='flag-5'>1-Wire</b> communicat

    1-Wire雙向電平轉(zhuǎn)換器應(yīng)用

    FPGA、微處理器、DS2482-100和DS2480B是常見的1-Wire主機器件。1-Wire/iButton從器件由Maxim生產(chǎn),該系列器件的典型工作電壓為2.8V至5.25V
    發(fā)表于 10-08 11:00 ?2645次閱讀
    <b class='flag-5'>1-Wire</b>雙向電平轉(zhuǎn)換器應(yīng)用

    1-Wire總線主機

    Abstract: Communication with 1-Wire slave devices requires a 1-Wire master. There are numerous ways
    發(fā)表于 10-19 17:02 ?53次下載

    如何計算該8位1-Wire CRC

    的硬件中生成,以驗證數(shù)據(jù)。 介紹 Maxim iButton產(chǎn)品是一系列器件,它們均按照稱為1-Wire協(xié)議的特定命令序列,通過一
    的頭像 發(fā)表于 05-14 11:47 ?2908次閱讀
    如何計算該8位<b class='flag-5'>1-Wire</b> CRC

    了解 1-Wire 的簡單性

    做得更好:了解 1-Wire 的簡單性
    的頭像 發(fā)表于 12-29 10:02 ?1131次閱讀
    <b class='flag-5'>了解</b> <b class='flag-5'>1-Wire</b> 的簡單性

    CRC(循環(huán)冗余校驗)應(yīng)用舉例

    CRC(循環(huán)冗余校驗)應(yīng)用舉例
    的頭像 發(fā)表于 05-16 16:12 ?1206次閱讀