calculate CRC for Modbus RTU


Thread Starter


How to genrate CRC for modbus RTU protocol,
Sample string.
Slave,Function,Address Hi,Address Lo,No.wordHi , No.wordsLo, CRC is 05,06,05,02,00,01,E882. in this E882 is the calculated CRC.

Can anyone explain me how this has been calculated.

The CRC-8 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**8, (shifted left 8 bits), then divided by X**8 + X**7 + X**2 + 1 expressed as a binary number (11000000000000101). The integer quotient digits are ignored and the 8-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**8 + X**7 + 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-8 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-8 is as follows:

1. Load a 8-bit register with all 1’s.

2. Shift the 8-bit register one bit to the right.

3a. If the bit shifted out to the right is one, exclusive OR the generating polynomial with the 8-bit register.

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

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

5. Repeat step 2 through 4 until all bytes of the message have been exclusive OR’rd with the 8-bit register and shifted 8 times.

6. The contents of the 8-bit register is a byte CRC error check and is added to the message most significant bits first.
UNfortunately, Modbus uses a CRC16 calculation as follows:
The Cyclical Redundancy Check (CRC) field is two bytes, containing a 16–bit binary value. The CRC value is calculated by the transmitting device, which appends the CRC to the message. The receiving device recalculates a CRC during receipt of the message, and compares the calculated value to the actual value it received in the CRC field. If the two values are not equal, an error results.

The CRC is started by first preloading a 16–bit register to all 1’s. Then a process begins of applying successive 8–bit bytes of the message to the current contents of the register. Only the eight bits of data in each character are used for generating the CRC. Start and stop bits, and the parity bit, do not apply to the CRC.

During generation of the CRC, each 8–bit character is exclusive ORed with the register contents. Then the result is shifted in the direction of the least significant bit (LSB), with a zero filled into the most significant bit (MSB) position. The LSB is extracted and examined. If the LSB was a 1, the register is then exclusive ORed with a preset, fixed value. If the LSB was a 0, no exclusive OR takes place. This process is repeated until eight shifts have been performed. After the last (eighth) shift, the next 8–bit character is exclusive ORed with the register’s current value, and the process repeats for eight more shifts as described above.

The final contents of the register, after all the characters of the message have been applied, is the CRC value.

A procedure for generating a CRC is:

1. Load a 16–bit register with FFFF hex (all 1’s). Call this the CRC register.

2. Exclusive OR the first 8–bit byte of the message with the low–order byte of the 16–bit CRC register, putting the result in the CRC register.

3. Shift the CRC register one bit to the right (toward the LSB), zero–filling the MSB. Extract and examine the LSB.

4. (If the LSB was 0): Repeat Step 3 (another shift). (If the LSB was 1): Exclusive OR the CRC register with the polynomial value A001 hex (1010 0000 0000 0001).

5. Repeat Steps 3 and 4 until 8 shifts have been performed. When this is done, a complete 8–bit byte will have been processed.

Sergio Toledano

Look at the following Intel 80XXX assambler example:
1- First Initialize CRC = FFFF
mov ax, CRC
xor al, Data { CRC_Lo = CRC_Lo XOR Data }
mov ecx, 9
dec cx
jcxz @@L2
shr ax, 1 { Extract/examine LSB }
jnc @@L1 { if LSB = 0 Repeat }
xor ax, $A001 { CRC = CRC XOR A001h }
jmp @@L1
@@L2: { Repeat 8 times }
mov CRC, ax { actualize CRC }
3- Send CRC at the end as MSB,LSB (unlike register
and value order)
best regards,<br>
Sergio Toledano<br>
[email protected]
It does only work, if you examine the LSB BEFORE(!) shifting the CRC to the right. In the assembler code you find the LSB after shifting in the carry bit.