How to Calculate CRC Modbus RTU

Asked

Viewed 1,067 times

3

I’m trying to calculate a crc Modbus in an application for PIC, but the returned crc is always incorrect compared to online simulators. follows 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 a 12 byte buffer for the calculation and at the end the buffer should come out along with crc.. but the crc calculation itself is returning the wrong value.. which may be wrong in the code?

in case my message should revert 8C0C but returns 68FE

1 answer

2


The error is happening due to the LSB be after the shift of the CRC16 recorder.

This check must occur before the shift operation, according to the 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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.