[bascom] CRC Check for Modbus with AVR


From "Mike Eitel" <meitel@smile.ch>
Date Tue, 20 Nov 2001 21:44:50 +0100

Hello

I'm on the way to implement a small modbus slave.
The data will be controlled via a defined CRC16 check, described below in
detail.

Befor reinventing the wheel;
Has anyone of the list already solved this function?
Eventually as a BASCOM Assembler LIB?

P.S The Bascom CRC8 is, as the name mentions; only made for 8 Bits

Thanks Mike



CRC-16 Cyclic Redundancy Check

The CRC-16 error check sequence is implemented as described in the following
paragraphs.

The message, (data bits only, disregarding start/stop and parity bits), is
considered as one continuous binary number whose most significant bit,
(MSB), is transmitted first.  The message is pre-multiplied by X**16,
(shifted left 16 bits), then divided by X**16 + X**15 + X**2 + 1 expressed
as a binary number (11000000000000101).  The integer quotient digits are
ignored and the 16-bit remainder (initialized to all ones at the start to
avoid the case where all zeroes being an accepted message), is appended to
the message, (MSB first), as the two CRC check bytes.  The resulting message
including the CRC, when divided by the same polynomial (X**16 + X**15 + X**2
+ 1), at the receiver will give a zero remainder if no errors have occurred.
(The receiving unit recalculates the CRC and compares it to the transmitted
CRC).  All arithmetic is performed modulo two, (no carries).  An example of
the CRC-16 error check for message HEX 0207, (address 2, function 7 or a
status request to slave number 2) follows:

The device used to serialize the data for transmission will send the
conventional LSB or right-most bit of each character first.  In generating
the CRC, the first bit transmitted is defined as the MSB of the dividend.
For convenience then, and since there are no carries used in arithmetic,
let's assume while computing the CRC that the MSB is on the right.  To be
consistent, the bit order of the generating polynomial must be reversed.
The MSB of the polynomial is dropped since it affects only the quotient and
not the remainder.  This yields 1010 0000 0000 0001, (HEX A001)..  Note that
this reversal of the bit order will have no effect whatever on the
interpretation or the bit order of characters external to the CRC
calculations.

The step by step procedure to form the CRC-16 is as follows:

1.      Load a 16-bit register with all 1's.

2.      Exclusive OR the first 8-bit byte with the high order byte of the
16-bit register, putting the result in the 16-bit register.

3.      Shift the 16-bit register one bit to the right.

4a.     If the bit shifted out to the right is one, exclusive OR the
generating polynomial 1010 0000 0000 0001 with the 16-bit register.

4b.     If the bit shifted out to the right is zero; return to step 3.

5.      Repeat steps 3 and 4 until 8 shifts have been performed.

6.      Exclusive OR the next 8-bit byte with the 16-bit register.

7.      Repeat step 3 through 6 until all bytes of the message have been
exclusive OR'rd with the 16-bit register and shifted 8 times.

8.      The contents of the 16-bit register are the 2 byte CRC error check
and is added to the message most significant bits first.


16-BIT REGISTER MSB                     Flag
(Exclusive OR)  1111    1111    1111    1111    
02                      0000    0010    
1111    1111    1111    1101    
Shift 1 0111    1111    1111    1110    1
Polynomial      1010    0000    0000    0001    
1101    1111    1111    1111    
Shift 2 0110    1111    1111    1111    1
Polynomial      1010    0000    0000    0001    
1100    1111    1111    1110    
Shift 3 0110    0111    1111    1111    0
Shift 4 0011    0011    1111    1111    1
Polynomial      1010    0000    0000    0001    
1001    0011    1111    1110    
Shift 5 0100    1001    1111    1111    0
Shift 6 0010    0100    1111    1111    1
Polynomial      1010    0000    0000    0001    
1000    0100    1111    1110    
Shift 7 0100    0010    0111    1111    0
Shift 8 0010    0001    0011    1111    1
Polynomial      1010    0000    0000    0001    
1000    0001    0011    1110    
07                      0000    0111    
1000    0001    0011    1001    
Shift 1 0100    0000    1001    1100    1
Polynomial      1010    0000    0000    0001    
1110    0000    1001    1101    
Shift 2 0111    0000    0100    1110    1
Polynomial      1010    0000    0000    0001    
1101    0000    0010    1111    
Shift 3 0110    1000    0010    0111    1
Polynommial     1010    0000    0000    0001    
1100    1000    0010    0110    
Shift 4 0110    0100    0001    0011    0
Shift 5 0011    0010    0000    1001    1
Polynomial      1010    0000    0000    0001    
1001    0010    0000    1000    
Shift 6 0100    1001    0000    0100    0
Shift 7 0010    0100    1000    0010    0
Shift 8 0001    0010    0100    0001    0
HEX 12                  HEX 41  
TRANSMITTED MESSAGE WITH CRC-16
(MESSAGE SHIFTED TO RIGHT TO TRANSMIT)

       12                   41                    07                   02

0001    0010    0100    0001    0000    0111    0000    0010
----------------------------------------------------------------------------
---------------------------------------------------------





Mit freundlichen Grüssen / Regards 
Michael / Mike Eitel
meitel@smile.ch <mailto:meitel@smile.ch> 

Hügelweg 7
CH-8224 Löhningen
Email:          meitel@smile.ch <mailto:meitel@smile.ch> 
Homepage:       http://home.sunrise.ch/meitel
<http://home.sunrise.ch/meitel> 
Tel:            +41 52 685 01 21
GSM             +41 79 416 50 22            or 

At work 
http://www.autotec.ch/ <http://www.autotec.ch/> 
AutoTec AG
Bohlstrasse 16
CH-8240 Thayngen 
Tel:    +41 52 645 25 25
Fax:    +41 52 645 25 99

Technical director 
eitel@autotec.ch <mailto:eitel@autotec.ch> 
Tel:    +41 52 645 25 35

<<attachment: winmail.dat>>