;***************************************************************
;
; 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
аENDC
аCBLOCK
а DataBlock: blocksize
а CRClo
а CRChi
а CRC8
аENDC
;***************************************************************
аorg 0а ; reset vector
аgoto main
аorg 04а ; interrupt vector
аretfieаа ; ain't no interrupt here mate
main
аcall init_CRC
аcall loaddata
аmovlw blocksize-2
аmovwf bcount
аaddlw DataBlock+1
аmovwf FSR
mainloop
а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
checkloop
а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
reception_good
а; nice one :)
аsleep
аgotoа reception_good
infiniteloop
аsleep
аgotoа infiniteloop ; ad infinitum
reception_error
а; oh dear :(
аgoto reception_error
;***************************************************************
; Initialise the CRC routine
;***************************
init_CRC
аclrf CRClo
аclrf CRChi
аclrf CRC8
аreturn
;***************************************************************
; 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
conventional
; 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
;
update_CRC
а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
temp1)
а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
difference
а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
аreturn
;***************************************************************
; 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
checking
; then this code is of no use.
;
;gen_parity
; 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.
;
loaddata
аmovlw blocksize
аmovwf bcount
аaddlw DataBlock-1
аmovwf FSR
loadloop
а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
аreturn
;***************************************************************
getdata:
а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
corrected.
;
; 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
update_CRC8
а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
аreturn
;***************************************************************
;ааа The
аEND
;аааааааааа , c'est
fini
╧хЁхщЄш:
/├ыртэр /
CBuild/
JavaScript 1.2-5.6/
Delifi6/
I2C ъюэЄЁюыыхЁ√/
AVR ъюэЄЁюыыхЁ√/
╧╦╚╤/
AHDL/
VHDL/
LPT EPP/ LPT ECP/ PCI/ COM port/ I2C/ RS-232/
Используются технологии uCoz
|