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");
}

Related Products

Pololu Simple Motor Controller 18v7 (Fully Assembled)
Pololu Simple Motor Controller 18v7
Pololu Simple High-Power Motor Controller 18v15 (Fully Assembled)
Pololu Simple High-Power Motor Controller 18v15
Pololu Simple High-Power Motor Controller 24v12 (Fully Assembled)
Pololu Simple High-Power Motor Controller 24v12
Pololu Simple High-Power Motor Controller 18v25
Pololu Simple High-Power Motor Controller 24v23
Log In
Pololu Robotics & Electronics
Shopping cart
(702) 262-6648
Same-day shipping, worldwide
Menu
Shop Blog Forum Support
My account Comments or questions? About Pololu Contact Ordering information Distributors