CRC16

Samstag, 09. April 2005 @ 20:50 CEST

Beitrag von: uho

naam: crc16.frt
auteur: Paul Wiegmans
datum: 10-3-2003
platform: 8051 ANS-=FORTH , CH-Forth (PC)
functie: CRC-16 berekenen zonder tabel geoptimaliseerd,
aangevuld met code aangepast voor 8-bits Forth (AVR) !

Berekent CRC-16 zonder tabel, naar een voorbeeldsource van internet.
Volgende voorbeeld wordt genoemd "CCITT compliant" .d.w.z. maakt gebruik
van de polynoom $1021 = x^16 + x^12 + x^5 + 1 .
Een tabel-crc16 implementatie is gebruikt in o.a. Xmodem implementatie...

unsigned char ser_data;
static unsigned int crc;

crc = (unsigned char)(crc >> 8) | (crc << 8);
crc ^= ser_data;
crc ^= (unsigned char)(crc & 0xff) >> 4;
crc ^= (crc << 12);
crc ^= ((crc & 0xff) << 4) << 1;

Zie ook : A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS
(http://www.microconsultants.com/tipc/crc/crc.txt)
of zoek in Google op "crc-16"

---------------------------------------------------------------------
Een andere implementatie, precies in spiegelbeeld!
te vinden op http://www.monitor-computing.pwp.blueyonder.co.uk/projects/crc16/

/* Hard wired for ^16+^12+^5+1, "CITT CRC16" - HDLC, X.25 */

unsigned int add2CRCCITT(unsigned char newData, unsigned int oldCRC)
{
oldCRC ^= newData;
oldCRC = (oldCRC >> 8) | (oldCRC << 8);
oldCRC ^= (oldCRC & 0xFF00) << 4;
oldCRC ^= oldCRC >> 12;
/* It might be better to use '(oldCRC >> 8) >> 4' above as some
compilers will optimise the shift by eight to a byte operation. */
oldCRC ^= (oldCRC & 0xFF00) >> 5;

return oldCRC;
}
--------------------------------------------------------------------


?def -crc [if] -crc [then] marker -crc

0 value crc bewaar crc voor 16-bit berekening
0 value crch crc high byte voor berekening op 8-bit Forth
0 value crcl crc low byte

------------[ DEBUG HULPJES ]--------------------------------------------

: .bin push base 2 to base 0
<# # # # # # # # # # # # # # # # # #> type pop base ;
: .byte push base hex 0 <# # # #> type pop base ;
: .deb16 cr crc .hex ;
: .deb8 cr crch .byte crcl .byte ;

----------[ CRC-16 ]-----------------------------------------------------

: calccrc ( n -- ) bereken crc-16
crc 8 lshift crc 8 rshift or to crc
crc xor to crc
crc $FF and 4 rshift crc xor to crc
crc 12 lshift crc xor to crc
crc $FF and 5 lshift crc xor to crc
;

----------[ CRC-16 VOOR 8-BIT FORTHS ]-----------------------------------

Nu het 16-bits CRC algorimte aangepast voor 8-bit Forth
Globale variabelen crch en crcl worden gebruikt voor opslaan van resultaat.

: 8bit $FF and ; normaliseer naar bytegrootte
nodig om te simuleren in 16-bit Forth

: calccrc8 ( n -- ) CRC-16 voor 8-bitters
crch crcl to crch to crcl
crcl xor to crcl
crcl 4 rshift crcl xor 8bit to crcl
crcl 4 lshift crch xor 8bit to crch
crcl 3 rshift crch xor 8bit to crch
crcl 5 lshift crcl xor 8bit to crcl
;

----------[ CRC-16 FORTH GEOPTIMALISEERD ]-------------------------------

: calccrcsnel ( n - ) beetje optimaliseren, overbodige variabele
referenties verwijderd en gebruikmaken van stack
crc dup 8 lshift
swap 8 rshift or xor
dup $FF and 4 rshift xor
dup 12 lshift xor
dup $FF and 5 lshift xor
to crc ... en opslaan voor volgende keer
;

: modelcrc ( n -- ) bereken CRC16 : eigen maaksel op basis
van modelalgoritme in referentietext
8 lshift crc xor to crc
8 0 do alle 8 bits ..
$8000 crc and if test hoogste bit
crc 1 lshift $1021 xor to crc 1 : xor met polynoom en schuif
else
crc 1 lshift to crc 0 : alleen schuiven
then
loop
;

---------[ TEST ]--------------------------------------------------------

create s 100 allot
s" AbCdEf!@#$6789" s place testgegevens voor CRC

0 value vector-crc

: doetest ( -- ) test een crc routine
0 to crc initialiseer crc
s c@ 0 do tel lengte van string af
s 1+ i + c@
dup emit vector-crc execute bereken crc voor elk teken in string
loop
cr ." De crc is: " crc .hex
;

: doetest8 ( -- ) testroutine voor 8-bits berekening
0 to crcl 0 to crch initialiseer crc
s c@ 0 do tel lengte van string af
s 1+ i + c@
dup emit calccrc8 bereken crc voor elk teken in string
loop
cr ." De crc is: " crch .byte crcl .byte
;

: testcrc ( -- ) test alle crc algoritmes
cr ." BEREKENING VAN CRC "

cr cr ." CRC volgens simpele c code "
['] calccrc to vector-crc
doetest

cr cr ." CRC volgens simpele geoptimaliseerde code "
['] calccrcsnel to vector-crc
doetest

cr cr ." CRC volgens model algoritme "
['] modelcrc to vector-crc
doetest

cr cr ." CRC 16 voor 8-bitters"
doetest8
;

: testk ( - ) "test klein"
cr ." TESTKLEIN "
cr ." CRC"
0 to crc
$88 calccrc
$22 calccrc
$44 calccrc
cr ." CRC voor 8-bitter"
0 to crcl
0 to crch
$88 calccrc8
$22 calccrc8
$44 calccrc8
;

getest in CH-Forth ( te downloaden van http://www.forth.hccnet.nl )
nog testen in 8051-ANS-Forth
nog testen in AVR-Forth
cr .( CRC berekening testen - 2003 Paul Wiegmans )
cr .( type: TESTCRC )
cr .( type: TESTK )

Kommentare (5)


Forth-Gesellschaft e.V.
/article.php/20050409205017537