Searching \ for 'CRC-16 algorithm' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/method/errors.htm?key=crc
Search entire site for: 'CRC-16 algorithm'.

Truncated match.
'CRC-16 algorithm'
1995\10\04@221812 by

On Wed, 4 Oct 1995, Falstaff wrote:

> Hi there,
>
> Does anyone have an implementation of CRC-16 for the PICs?  If not, a pointer
> to a C sources is fine too, assuming it doesn't use a table (most C
> implementations use a 512-byte table to speed up calculations, but
> that doesn't go as well in a 2k environment as it does under UNIX...)
>
> Frank
>
> "It's justice, Jim, but not as we know it."
> ------------------------------------------------------------------------
> Frank A. Vorstenbosch        +31-(70)-355 5241        falstaffxs4all.nl
>

I have a C source code listing I found in a Modicon Modbus Protocol Ref.
Guide.  If you would like I can fax  a copy to you.  Just Email me your
Fax Number.

-------------------------------------------------------------------------------
Marc Laclair                              __  __     ____  ___       ___ ____
laclairprimenet.com                     /__)/__) / / / / /_  /\  / /_    /
http://www.primenet.com/~laclair/       /   / \  / / / / /__ /  \/ /___  /
-------------------------------------------------------------------------------
> On Wed, 4 Oct 1995, Falstaff wrote:
>
> > Hi there,
> >
> > Does anyone have an implementation of CRC-16 for the PICs?  If not, a
pointer

Here's a routine to calculate a running CRC. The unsigned short (16 bits)
variable crc_value is initialized to zero. Then just call crc_chr with each
byte and it will accumulate a CRC.

static void
crc_chr(c)
{
register int    i, j;

for(i = 0 ; i != 8 ; c >>= 1, i++) {
j = (c ^ (crc_value >> 15)) & 1;
crc_value <<= 1;
if(j)
crc_value ^= 0x8005;
}
}

--
Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
clydehitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
http://www.hitech.com.au  | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
HI-TECH C: Compiling the real world...
>Here's a routine to calculate a running CRC. The unsigned short (16 bits)
>variable crc_value is initialized to zero. Then just call crc_chr with each
>byte and it will accumulate a CRC.
>
>static void
>crc_chr(c)
>{
>        register int    i, j;
>
>        for(i = 0 ; i != 8 ; c >>= 1, i++) {
>                j = (c ^ (crc_value >> 15)) & 1;
>                crc_value <<= 1;
>                if(j)
>                        crc_value ^= 0x8005;
>        }
>}

OK, I don't understand C too well, but I think I see what's going on well
enought to take a stab at a PIC translation.  I'm assuming the process is:
For each of the 8 bits of data coming in, X-or the high bit of the CRC value
with the low bit of the data.  Next, shift the CRC value left one bit, and
if the X-or was 1, X-or the new CRC value with 8005 hex.

PIC Code (perhaps not optimized, but I believe equivalent to the heart of
the C above...):

This works on one bit (bit 0) of char at a time.  If you are CRC'ing 8 bits
at a time, you'll need to set up an outer loop that counts the bits and
shifts char right once each time.  The initial setting to 0 isn't included
either.  crcl, crch, and char are RAM locations.

movlw   b'10000000'     ;Xor new bit with CRC bit before shifting.
btfsc   char,0          ;only if char bit is 1.
xorwf   crch,f          ;Xor char[0] with crc[15] -> crc[15]
clrc
rlf     crcl,f
rlf     crch,f          ;Rotate 0 into low bit of CRC, xor result to CY
;----- See below for alternate ending.
skpc                    ;If result is 1 -- need to xor generator in.
goto    out             ;No, done.
xorwf   crch,f          ;Xor in \$80 (Still in W from above-- Neat.)
movlw   b'00000101'     ;Low byte of generator
xorwf   crcl,f          ;Xor in.
out                             ;Done.

This executes in either 9 or 11 cycles.  A constant execution time version
could be done by replacing the code below the ';----' with:

skpnc                   ;Skip if result was 0-- don't xor.
xorwf   crch,f          ;Xor with \$80 (still in W from above).
movlw   b'00000101'     ;Load the low generator byte
skpnc
xorwf   crcl,f          ;Xor if required.

The modified version always takes 11 cycles regardless of the data content.
Further variations are undoubtably possible.

- Mike
Hope this helps.  No guarantees expressed or implied, etc.

>
>
>
>--
> Clyde Smith-Stubbs       | HI-TECH Software,       | Voice: +61 7 3300 5011
> clydehitech.com.au      | P.O. Box 103, Alderley, | Fax:   +61 7 3300 5246
>http://www.hitech.com.au  | QLD, 4051, AUSTRALIA.   | BBS:   +61 7 3300 5235
>                    HI-TECH C: Compiling the real world...
>
On Wed, 4 Oct 1995, Falstaff wrote:

> Does anyone have an implementation of CRC-16 for the PICs?  If not, a pointer
> to a C sources is fine too, assuming it doesn't use a table (most C
> implementations use a 512-byte table to speed up calculations, but
> that doesn't go as well in a 2k environment as it does under UNIX...)

CRC-16 is basically a X^16 + X^15 + X^2 + 1 polynomial. That is, if
you XOR the input data bit with bits 15(MSB), 14 and 1 and shift it
in the CRC-16 register, repeat the step 8 times, you got it.

Dallas Semiconductors gives three assembler implementations in the
book 'Touch Memory Standards'. They are easy to port to PIC asm and
at least one of them is very compact:

crc16:
mov     b, #08h ; counter
get_bit:
rrc     a       ; acc contains the present byte to be CRC'ed
push    acc     ; save acc
jc      in_1
mov     c, crc_lo.0
jmp     cont
in_1:
mov     c, crc_lo.0
cpl     c
cont:
jnc     shift
cpl     crc_hi.6
cpl     crc_lo.1
shift:
mov     a, crc_hi       ; this can be done easier in PIC asm
rrc     a                       ; by rotating the registers directly
mov     crc_hi, a
mov     a, crc_lo
rrc     a
mov     crc_lo, a
pop     acc             ; restore byte
djnz    b, get_bit
ret

This should be easier to port using the Parallax asm. I apologize for
any errors in the code.

Cheers,
Richard
Cape Town
----------

Here is a implimintation of CRC in basic that
I got off the net.  I haven't tried it, nor looked at
it close.

But it may help validate your implimentation
in PIC code if they both come up with same answer.

Bill C.

*************************

DECLARE FUNCTION CRC16& (Block\$)
DECLARE FUNCTION CRC32& (Block\$)

'simple usage.
print "CRC16 is:",crc16&("Now is the Time")
print "CRC32 is:",crc32&("Now is the Time")

DEFINT A-Z
FUNCTION CRC16& (B\$)      'Calculates CRC for Each Block

DIM Power(0 TO 7)                              'For the 8 Powers of 2
DIM CRC AS LONG

FOR I = 0 TO 7                                 'Calculate Once Per Block to
Power(I) = 2 ^ I                            ' Increase Speed Within FOR J
NEXT I                                         ' Loop
CRC = 0                                        'Reset for Each Text Block
FOR I = 1 TO LEN(B\$)                           'Calculate for Length of Block
ByteVal = ASC(MID\$(B\$, I, 1))
FOR J = 7 TO 0 STEP -1
TestBit = ((CRC AND 32768) = 32768) XOR ((ByteVal AND Power(J)) =
Power(J))
CRC = ((CRC AND 32767&) * 2&)
IF TestBit THEN CRC = CRC XOR &H1021     ' <-- This for 16 Bit CRC
NEXT J
NEXT I
CRC16& = CRC                               'Return the Word Value
END FUNCTION

DEFSNG A-Z

FUNCTION CRC32& (B\$)      'Calculates CRC for Each Block

DIM Power(0 TO 7)                              'For the 8 Powers of 2
DIM CRC AS LONG

FOR I = 0 TO 7                                 'Calculate Once Per Block to
Power(I) = 2 ^ I                            ' Increase Speed Within FOR J
NEXT I                                         ' Loop
CRC = 0                                        'Reset for Each Text Block
FOR I = 1 TO LEN(B\$)                           'Calculate for Length of Block
ByteVal = ASC(MID\$(B\$, I, 1))
FOR J = 7 TO 0 STEP -1
TestBit = ((CRC AND 32768) = 32768) XOR ((ByteVal AND Power(J)) =
Power(J))
CRC = ((CRC AND 32767&) * 2&)
IF TestBit THEN CRC = CRC XOR &H8005     ' <-- This for 32 Bit CRC
NEXT J
NEXT I
CRC32& = CRC                               'Return the Word Value
END FUNCTION

**********************

More... (looser matching)
- Last day of these posts
- In 1995 , 1996 only
- Today
- New search...