📄 理解和运用maxim ibutton产品中的循环冗余校验(crc) - maxim.htm
字号:
(Current_CRC16_Lo) EXOR
(输入字)<BR><BR>在低阶字节表中决定新的CRC值低阶字节(New_CRC16_Lo)的索引计算公式如下:
<BR><BR>New_CRC16_Lo = (CRC16_Tablo[I]) EXOR
(Current_ CRC16_Hi) I = 0至255;<BR>这里: I =
(Current_CRC16_Lo) EXOR
(输入字)<BR><BR><B>图4</B>所示为如何实现该方法的一个实例。<BR><BR>
<H3>例4. 计算CRC-16的汇编语言程序</H3><PRE>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
</PRE>
<H3>例5. 利用查找表进行CRC-16计算的汇编程序</H3><PRE>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
</PRE><IMG alt="图4. CRC-16计算和查表方法的比较"
src="理解和运用Maxim iButton产品中的循环冗余校验(CRC) - Maxim.files/542Fig05.gif"><BR><I>图4.
CRC-16计算和查表方法的比较</I><BR><BR>例6描述了一种令人感兴趣的的中间方案。该程序利用<B>图5</B>所示的公式,通过对当前整个CRC的值和输入字节进行运算来生成CRC-16。同时在图中还给出了该等式的推导过程,用字母字符表示当前16位CRC值,用数字字符表示输入字节的位。8次移位后就得到了所示的等式,这些等式随后可以预计算出大部分的新CRC值。注意:例如ABCDEFGH01234567
(定义为所有位异或的结果)数字量等于输入数据和当前CRC低字节的奇偶性。与前面的按位计算或查表方法相比较,这种方法可以减少计算时间,或减少存储空间。最后,应说明的是,前面介绍的CRC-16函数的两种特性在这里也用作调试准则。其第一个特性与DOW
CRC的情况完全相同,即如果当前CRC寄存器的16位内容作为后续的16位输入数据,则得到的CRC也总为0000H。CRC功能的第二个特性与DOW
CRC相似,如果把当前CRC寄存器的16位反码也作为后续的16位输入数据,则CRC结果总为B0
01H。这两个CRC-16特性的证明方法也与DOW CRC相似。<BR><BR>
<H3>例6. 高速CRC-16算法的汇编语言程序 </H3><PRE>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
</PRE><BR><A
href="http://www.maxim-ic.com.cn/images/appnotes/27/542Fig06.gif"><IMG
alt="图5. 高速CRC-16的计算方法"
src="理解和运用Maxim iButton产品中的循环冗余校验(CRC) - Maxim.files/542Fig06-T.gif"
border=0><B
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -