There are many correct 'C' routines published for Modbus RTU CRC calculation. However if for you want to implement the procedure in another language (Power Basic for example) and implement it from the documented description of Modbus RTU CRC calculation in the Modicon Modbus Protocol guide PI-MBUS-300 (Rev J for example) you will find it gives the wrong result
The description is wrong because in its loop, testing CRC LSB and shifting through 8 bits, it examines the LSB value of the CRC register after a shift of the register and not before. Whether or not to XOR the CRC with the polynomial after the shift depends on the CRC LSB value before the shift. Below the description of it is modified to an order which gives the correct result.
1. Load a 16-bit register with FFF 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 CRC register
3. Extract and examine the LSB
4. (If the LSB was 1): Shift the CRC one bit to the right towards the LSB, zero-filling the MSB
Exclusive OR the CRC register with the polynomial value A001 hex (1010 0000 0000 0001)
(if the LSB was 0): Just shift the CRC one bit to the right towards the LSB, zero-filling the MSB.
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
6. Repeat Steps 2 through 5 for the next 8-bit byte of the message.
Continue doing this until all bytes have been processed
7. The final contents of the CRC register is the CRC value
8. When the CRC is placed in the message its upper and lower bytes must be swapped as described below
Placing the CRC in the Message
When the 16-bit CRC (two 8 bit bytes) is transmitted in the message, the low-order byte will be transmitted first, followed by the high order byte. For example, if the CRC value is 1241 hex (0001 0010 0100 0001):
The description is wrong because in its loop, testing CRC LSB and shifting through 8 bits, it examines the LSB value of the CRC register after a shift of the register and not before. Whether or not to XOR the CRC with the polynomial after the shift depends on the CRC LSB value before the shift. Below the description of it is modified to an order which gives the correct result.
1. Load a 16-bit register with FFF 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 CRC register
3. Extract and examine the LSB
4. (If the LSB was 1): Shift the CRC one bit to the right towards the LSB, zero-filling the MSB
Exclusive OR the CRC register with the polynomial value A001 hex (1010 0000 0000 0001)
(if the LSB was 0): Just shift the CRC one bit to the right towards the LSB, zero-filling the MSB.
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
6. Repeat Steps 2 through 5 for the next 8-bit byte of the message.
Continue doing this until all bytes have been processed
7. The final contents of the CRC register is the CRC value
8. When the CRC is placed in the message its upper and lower bytes must be swapped as described below
Placing the CRC in the Message
When the 16-bit CRC (two 8 bit bytes) is transmitted in the message, the low-order byte will be transmitted first, followed by the high order byte. For example, if the CRC value is 1241 hex (0001 0010 0100 0001):
Addr | Func | Data Count | Data | Data | Data | Data | Data | CRCLo 41 | CRCHi 12 |