6.7.6. CRC Computation in C

Simple Example

The following example program shows how to compute a CRC byte in the C language. The outer loop processes each byte, and the inner loop processes each bit of those bytes. In the example main() routine, this is applied to generate the CRC byte in the message 0x83, 0x01, that was used in Section 6.5. The getCRC() function will work without modification in both Arduino and Orangutan programs.

const unsigned char CRC7_POLY = 0x91;

unsigned char getCRC(unsigned char message[], unsigned char length)
{
  unsigned char i, j, crc = 0;

  for (i = 0; i < length; i++)
  {
    crc ^= message[i];
    for (j = 0; j < 8; j++)
    {
      if (crc & 1)
        crc ^= CRC7_POLY;
      crc >>= 1;
    }
  }
  return crc;
}

int main()
{
  // create a message array that has one extra byte to hold the CRC:
  unsigned char message[3] = {0x83, 0x01, 0x00};
  message[2] = getCRC(message, 2);
  // send this message to the Simple Motor Controller
}
Advanced Example

The following example program shows a more efficient way to compute a CRC in the C language. The increased efficiency is achieved by pre-computing the CRCs of all 256 possible bytes and storing them in a lookup table, which can be in RAM, flash, or EEPROM. These table values are then XORed together based on the bytes of the message to get the final CRC. In the example main() routine, this is applied to generate the CRC byte in the message 0x83, 0x01, that was used in Section 6.5.

#include <stdio.h>

const unsigned char CRC7_POLY = 0x91;
unsigned char CRCTable[256];

unsigned char getCRCForByte(unsigned char val)
{
  unsigned char j;

  for (j = 0; j < 8; j++)
  {
    if (val & 1)
      val ^= CRC7_POLY;
    val >>= 1;
  }

  return val;
}

void buildCRCTable()
{
  int i;

  // fill an array with CRC values of all 256 possible bytes
  for (i = 0; i < 256; i++)
  {
    CRCTable[i] = getCRCForByte(i);
  }
}

unsigned char getCRC(unsigned char message[], unsigned char length)
{
  unsigned char i, crc = 0;

  for (i = 0; i < length; i++)
    crc = CRCTable[crc ^ message[i]];
  return crc;
}

int main()
{
  unsigned char message[3] = {0x83, 0x01, 0x00};
  int i, j;

  buildCRCTable();
  message[2] = getCRC(message, 2);

  for (i = 0; i < sizeof(message); i++)
  {
    for (j = 0; j < 8; j++)
      printf("%d", (message[i] >> j) % 2);
    printf(" ");
  }
  printf("\n");
}