; crc2.asm David Roussel 12/2/1998


; CRC calculation test code



;There are two main routines one for a CRC-16 update and one for a ATM

;HEC CRC update.а Both routines use indirect addressing to load the data

;byte and return after updating the CRC shift register.а So to process a

;16 byte block the shift reg should be set to zero and the update routine

;called once per byte, whilst updating the FSR between calls.

;Both routines are highly optimised and do not need look up tables.


аLIST P=16F84, R=dec, n=0

аINCLUDE <p16F84.inc>




rambase = 0Chа ; start address of user file registers

blocksize = 10а ; total size of block to compute CRC on,

аа ; including the 2 CRC bytes themselves

аа ; must be greater than 2, since using CRC-16




аCBLOCK rambase

а temp1 ; general purpose regs

а temp2

а temp3

а temp4

а bcount ; counter for bytes in datablock




а DataBlock: blocksize

а CRClo

а CRChi

а CRC8





аorg 0а ; reset vector

аgoto main


аorg 04а ; interrupt vector

аretfieаа ; ain't no interrupt here mate



аcall init_CRC

аcall loaddata

аmovlw blocksize-2

аmovwf bcount

аaddlw DataBlock+1

аmovwf FSR


аcallа update_CRC8


аdecf FSR, Fа ; advance to next message byte

аdecfsz bcount, Fа ; are we done yet?

аgotoа mainloop


а; copy calculated CRC into message and then recompute

а; to see if we get remainder zero.


аmovf CRC8, W

аmovwf DataBlock+1


аcallа init_CRC


аmovlw blocksize-1

аmovwf bcount

аaddlw DataBlock

аmovwf FSR


аcallа update_CRC8


аdecf FSR, Fа ; advance to next message byte

аdecfsz bcount, Fа ; are we done yet?

аgotoа checkloop


а; was there an error?

аmovf CRClo, W

аiorwf CRChi, W

аbtfss STATUS, Z ; z=1 if CRC-16==0

аgoto reception_error



а; nice one :)


аgotoа reception_good




аgotoа infiniteloop ; ad infinitum



а; oh dear :(

аgoto reception_error



; Initialise the CRC routine




аclrf CRClo

аclrf CRChi

аclrf CRC8




; update_CRC


;а This function reads the current input byte

;а form INDF, and computes the next stage in

;а the CRC-16 calculation.


;а The CRC-16 modulo-2 polynomial is:

;аааа X^16 + X^15 + X^2 + 1


;а The algorithm used based on an article:


; Aram Perez, 'Byte-Wise CRC Calculations', IEEE Micro June 1983.


; It works by compling all the operations needed in 8 steps

; of a shift register CRC implemetation into one 8-bit byte

; calculation.


;а Perez's Algorithm:

; 1) XOR the input byte with the low-order byte of

;а the CRC register to obtain T.

; 2) Shift the CRC register eight bits to the right.

; 3) Calculate the 16-bit value V from T.

;а (this is the cumulative effect of the 8 steps)

; 4) XOR the CRC register with the calculated value.

; 5) Repeat 1-4, for all message bytes


;а My version:

; Steps 2) and 3) are combined onto one. (In fact most of the routine

; seems to be be block of xors shifts and movs).

; Perez labeled his bits from 1 to 16, I label mine in a more


; manner: from 15 to 0, in


;а To calculate the next CRC define:

; Sа s[15:0] = the 16 bits of the CRC-16 check digit

; S' s' = the previous value of the CRC (should be set to zero before

first iteration)

; Bа b[7:0] = the 8-bit input byte

; Tа t[7:0] = s[15:8] + b[7:0]

; p := t[0] + t[1] + t[2] + t[3] + t[4] + t[5] + t[6] + t[7] ; the even

parity bit


; where (+) is modulo-2, e.g. 1 + 1 = 0 (the eXclusixe-OR operation)


; s[ 0] :=а p

; s[ 1] :=а pаа + t[0]

; s[ 2] := t[0] + t[1]

; s[ 3] := t[1] + t[2]

; s[ 4] := t[2] + t[3]

; s[ 5] := t[3] + t[4]

; s[ 6] := t[4] + t[5]

; s[ 7] := t[5] + t[6]


; s[ 8] := t[6] + t[7] + s'[0]

; s[ 9] := t[7]ааааааа + s'[1]

; s[10] := 0аааааааааа + s'[2]

; s[11] := 0аааааааааа + s'[3]

; s[12] := 0аааааааааа + s'[4]

; s[13] := 0аааааааааа + s'[5]

; s[14] := 0аааааааааа + s'[6]

; s[15] := pаааааааааа + s'[7]


; Program sizeа : 32 instructions

; Execution time : 32 cycles, with no branching

; State variablesа : CRChi and CRClo

; Temporary varaiblesа : temp1, temp2




аbcf STATUS, C

аmovf INDF, W

аxorwf CRChi, W

аmovwf temp1а ; temp1 := INDF XOR CRChi

ааа ; temp1 == T

а; Calculate X

аrrf temp1, W

аxorwf temp1, W ; temp1 == Q

аmovwf temp2а ; temp2 := (temp1 XOR (temp1 << 1))


а; move 2 msb of temp2 into 2 lsb of CRChi, via CARRY

аclrf CRChi

аbcf STATUS, C

аrlf temp2, F

аrlf CRChi, F ; first bit

аrlf temp2, F

аrlf CRChi, F ; second bit


а; calculate p, using parity routine

а; at the end of this block temp1='xxxxxxzp'

а; where p is the even parity bit, and z = p xor (bit7 of the orginal


аbcf STATUS, C

аrrf temp1, W

аxorwf temp1, F

аswapf temp1, W

аxorwf temp1, W

аmovwf temp1

аrrf temp1, F

аrrf temp1, F

аxorwf temp1, F


аmovf CRClo, W

аxorwf CRChi, F


аmovlw B'00000011'

аandwf temp1, W ; W := 000000zp

аxorwf temp2, W ; actually this could be an ior, but it makes no


аmovwf CRClo


аrrf temp1, F ; move bit p into C

аclrf temp1

аrrf temp1, W ; W now contains p of temp1, only, in msb

аxorwf CRChi, F ; so now the msb of CRChi is xored with the parity bit






; Generate Even Parity Bit

;а Input: given data byte in temp1

;а Ouput: return B'xxxxxxxp' in temp1 ,where p=partiy bit


; (this routine is in-lined to the above routine, but I have included it


; seperately in case you need to generate parity.

; But if you are using a CRC, which is altogether better than parity


; then this code is of no use.



; bcf STATUS, C

; rrf temp1, W

; xorwf temp1, F

; swapf temp1, W

; xorwf temp1, W

; movwf temp1

; rrf temp1, F

; rrf temp1, F

; xorwf temp1, F



; Fills up the message buffer files with data from a table.



аmovlw blocksize

аmovwf bcount

аaddlw DataBlock-1

аmovwf FSR


аmovf bcount, W

аaddlw -1

аcall getdata

аmovwf INDF

аdecf FSR, Fа ; advance to next message byte

аdecfsz bcount, F ; are we done yet?

аgotoа loadloop






аaddwf PCL, F

аretlw 0 ; Initial CRClo

аretlw 0 ; Initial CRChi

аretlw 'H'

аretlw 'e'

аretlw 'l'

аretlw 'l'

аretlw 'o'

аretlw ' '

аretlw ':'

аretlw ')'





; update 8-bit CRC



; Based on the ATM HEC CRC (don't you just love TLAs?)

;аа <Asynchronous Transmission Mode>

;аа <Header Error Control>

;аа <Cyclic Redundancy Check>

; Generator Polynomial:

;а X^8 + X^2 + X + 1

; which is expurgated, meaning single bit errors can be isolated and



; registers used:

;аа CRC8 - the 8-bit CRC digit and result

;аа INDF - contains the data byte to process

;аа dbyte - local variable


; Calculation Table:а bi = si XOR xi, or i=0..7 and x is input byte, s

is CRC digit.


; s7 s6 s5 s4 s3 s2 s1 s0

; -----------------------а .

; b7 b6 b6 b4 b3 b2 b1 b0 /|\

; b6 b5 b4 b3 b2 b1 b0 b7а |а XOR

; b5 b4 b3 b2 b1 b0 b6 b6а |

;аааааааааааа b7 b6а |


; Program sizeа : 15 instructions

; Execution time : 15 cycles, with no branching

; State variablesа : CRC8

; Temporary varaiblesа : dbyte


#define dbyte temp1



аmovf INDF, W

аxorwf CRC8 ,W

аmovwf dbyteа ; {b7 b6 b5 b4 b3 b2 b1 b0} := INDF XOR CRC8

аmovwf CRC8а ; CRC8 := dbyte

аrlf dbyte, W ; C := {b7}

аrlf dbyte, W ; W := {b6 b5 b4 b3 b2 b1 b0 b7}

аxorwf CRC8,а F ; CRC8 := CRC8 XOR W

аswapf dbyte, W ; W := {b3 b2 b1 b0 b7 b6 b5 b4}

аandlw 0x0Cа ; W := {0а 0а 0а 0а b7 b6 0а 0 }

аxorwf CRC8,а F

аrlf dbyte, W ; C := {b6}

аrlf dbyte, F ; dbyte := {b6 b5 b4 b3 b2 b1 b0 b6}, C := b7

аrlf dbyte, W ; C := b6

аrlf dbyte, F ; dbyte := {b5 b4 b3 b2 b1 b0 b6 b6}, C := b6

аxorwf CRC8,а F






;ааа The


;аааааааааа , c'est fini


╧хЁхщЄш: /├ыртэр / CBuild/ JavaScript 1.2-5.6/ Delifi6/ I2C ъюэЄЁюыыхЁ√/ AVR ъюэЄЁюыыхЁ√/ ╧╦╚╤/ AHDL/ VHDL/
LPT EPP/ LPT ECP/ PCI/ COM port/ I2C/ RS-232/
╨хщЄшэу@Mail.ru Rambler's Top100 Rambler's Top100 Rambler's Top100    
Используются технологии uCoz