CRC-16 Code for Modbus with ARM7TDMI

Post a reply


Enter the code exactly as it appears. All letters are case insensitive, there is no zero.
Smilies
:D :) :( :o :shock: :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:
BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON
Topic review
   

Expand view Topic review: CRC-16 Code for Modbus with ARM7TDMI

Re: CRC-16 Code for Modbus with ARM7TDMI

Post by Tomi Engdahl on Thu Oct 23, 2008 8:12 am

Another C code that claims to do the same CRC16 calculation:

Here is a direct copy of the CRC spec that pertains to calculating the
CRC16:

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 theMSB. 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.
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 into the message, its upper and lower bytes
must be swapped as described below.

Code: Select all
unsigned short
getCRC16( unsigned char * s )
{

        unsigned short CRCRegFull;
        int index;
        int x;
        int str_length;
        unsigned char temp;

        /* load the register with 0xFFFF */
        CRCRegFull = 0xFFFF;
       
        str_length = strlen( s );

        for ( index=0;index<str_length;index++)
        {

                temp = s[index];

                /* XOR Low-Byte order of CRCReg and s */

                CRCRegFull ^= (temp<<8);
               

                  for (x=0;x<8;x++ )
                {

                       
                        /* Bit-shift once to the right */
                        CRCRegFull >>= 1;

                        /* Evaluate LSB. If it == 1, XOR with 0xA001 */
                        if ( 1 & CRCRegFull )
                        {
                                CRCRegFull ^= 0xA001;
                        }

                } /* Repeat for each bit in the byte */
               

        } /* Repeat for each character in teh sequence */

        /* Swap the bytes for insertion into the message */
        return ( (CRCRegFull & 0xFF) * 256 ) + (CRCRegFull>>8);

} /* getCRC16 */


Souce: http://coding.derkeiler.com/Archive/C_C ... /0627.html

More links:

Calculating Modbus CRC16
http://coding.derkeiler.com/Archive/C_C ... /0627.html

On-line CRC calculation and free library
http://www.lammertbies.nl/comm/info/crc ... ation.html

Needing algorithm for Modbus CRC calculation: Request for library inclusion of Modbus CRC16 algorithm
http://www.lammertbies.nl/forum/viewtopic.php?t=6

Re: Calculating Modbus CRC16
http://coding.derkeiler.com/Archive/C_C ... /0645.html

CRC16 for ModBus RTU calculation
http://www.experts-exchange.com/Program ... 79912.html
"ModBus uses the formula: 2^15 + 2^13 + 2^0"

Re: CRC-16 Code for Modbus with ARM7TDMI

Post by Tomi Engdahl on Thu Oct 23, 2008 7:41 am

An example of a C language function performing Modbus CRC16 generation.
Code: Select all

WORD CRC16 (const BYTE *nData, WORD wLength)
{
static const WORD wCRCTable[] = {
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

BYTE nTemp;
WORD wCRCWord = 0xFFFF;

   while (wLength--)
   {
      nTemp = *nData++ ^ wCRCWord;
      wCRCWord >>= 8;
      wCRCWord ^= wCRCTable[nTemp];
   }
   return wCRCWord;

}


Source: http://www.modbustools.com/modbus_crc16.htm

CRC-16 Code for Modbus with ARM7TDMI

Post by Altz- on Wed Jun 13, 2007 1:58 am

i'm doing a project of arm processor which will be interfaced with the plc.so i'm finding some difficulty with CRC16 code for modbus. if some one is really having some knowledge abt this, he should plz help me.

Top

cron