How to Calculate CRC Modbus RTU

2

I'm trying to calculate a crc modbus in an application for PIC, but the crc returned is always incorrect compared to online simulators .. follow the code

void CRC (unsigned char* msg, unsigned char* out)
{
    //char CRC16[2] = {0xFF,0xFF};
    unsigned int CRC16 = 0xffff; 
    unsigned int poly =  0xA001;
    unsigned char data[14];
    unsigned char crc [2];

    for (int i=0; i<14; i++)
    {   
        CRC16 = (unsigned int)msg[i] ^ CRC16; //alteração data para msg
        for (int j=0; j<8; j++)
        {  
            CRC16 >>= 1;

            if(CRC16 & 0x0001 == 1) 
            {
                CRC16 ^= poly; 
            }
        }
    }
    crc[0] = CRC16 >> 8;
    crc[1] = CRC16 & 0b0000000011111111 ;
    strcpy (data,msg);
    strcat (data,crc);
    strcpy (out,data);


} 

I enter with a buffer of 12 bytes for the calculation and in the end the buffer should come out next to the crc .. but the crc calculation itself is returning the wrong value .. what could be wrong in the code?

In case my message should return 8C0C but returns 68FE

    
asked by anonymous 28.03.2018 / 19:05

1 answer

1

The error is occurring because the LSB check is after the shift of the CRC16 register.

This check must occur before the shift operation, as modified code below:

void CRC (unsigned char* msg, unsigned char* out)
{
    //char CRC16[2] = {0xFF,0xFF};
    unsigned int CRC16 = 0xffff;
    unsigned int poly =  0xA001;
    unsigned char data[14];
    unsigned char crc [2];

    for (int i=0; i<14; i++)
    {
        CRC16 = (unsigned int)msg[i] ^ CRC16; //alteração data para msg
        for (int j=0; j<8; j++)
        {
          // AQUI: primeiro verifica, depois executa o shift
          if(CRC16 & 0x0001 == 1)  {
            CRC16 >>= 1;
            CRC16 ^= poly;
          } else {
            CRC16 >>= 1;
          }
        }
    }
    crc[0] = CRC16 >> 8;
    crc[1] = CRC16 & 0b0000000011111111 ;
    strcpy (data,msg);
    strcat (data,crc);
    strcpy (out,data);
}

Reference (pdf): MODBUS over Serial Line

    
13.05.2018 / 22:51