CRC16 functions

Beta Testing discussion on mikroC PRO for PIC.
Post Reply
Author
Message
cgengineer
Posts: 18
Joined: 11 Apr 2017 06:17
Location: Italy

CRC16 functions

#1 Post by cgengineer » 20 Apr 2017 17:51

Hi everyone,

I saw that one can vote if wants a CRC16 calculation library. I have a simple library that works in about 25000 devices built by me.
I would like to thank MikroElektronica team for my Beta Testing licence with a little present:

Code: Select all

/* Table of CRC values for high–order byte */
const char _CRCHi[]  = {
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
   0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
   0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
   0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
   0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
   0x40
};

/* Table of CRC values for low–order byte */
const char _CRCLo[] = {
   0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
   0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
   0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
   0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
   0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
   0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
   0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
   0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
   0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
   0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
   0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
   0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
   0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
   0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
   0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
   0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
   0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
   0x40
};


union {
    unsigned char b[2];
    unsigned int d;
} __serial_crc;


void InitCrc() {
          __serial_crc.d = 0xFFFF;
}


// Purpose:    Calculate crc of data and updates global crc
// Inputs:     Character
// Outputs:    None
void CalcCrc(unsigned char ucdata) {
    unsigned char uIndex ; // will index into CRC lookup table

    uIndex = __serial_crc.b[1] ^ ucdata; // calculate the CRC
    __serial_crc.b[1] = __serial_crc.b[0] ^ _CRCHi[uIndex];
    __serial_crc.b[0] = _CRCLo[uIndex];

}

void GetCrcByte(unsigned char* ucCrcHi, unsigned char* ucCrcLow)  {
          *ucCrcHi = __serial_crc.b[1];
          *ucCrcLow = __serial_crc.b[0];
}

void GetCrcWord(unsigned int* uiCrc) {
          *uiCrc = __serial_crc.d;
}
If you want to use it, just save on a C file and then include in your project. When you need to calculate a CRC you have to call the InitCRC() function and then call the CalcCrc() for every byte you need to include in the check.
When you are done and you need the CRC word, just call the GetCrcWord()

Example:

Code: Select all

unsigned char ucDataToTransfer[50];
unsigned char uiCRC;
unsigned char i;
....
InitCrc();
for (i = 0; i < 50; i++)   CalcCrc(ucDataToTransfer[i];
GetCrcWord(&uiCRC);
...
Enjoy!
All the best
CG

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: CRC16 functions

#2 Post by filip » 21 Apr 2017 15:56

Hi,

Thanks for sharing! :)

Could you also upload in on LibStock please ?

Regards,
Filip.

cgengineer
Posts: 18
Joined: 11 Apr 2017 06:17
Location: Italy

Re: CRC16 functions

#3 Post by cgengineer » 21 Apr 2017 17:09


electrogera
Posts: 23
Joined: 24 Dec 2008 07:55
Location: Tijuana Baja California México
Contact:

Re: CRC16 functions

#4 Post by electrogera » 20 May 2017 23:09

I am extremely thankful for your code "cgengineer", I have been suffering for the last 4 weeks trying to learn how CRC works and how to implement this function it on one of my hobby projects, but you really save me, thank you very much..
Helping others we can learn more every day

cgengineer
Posts: 18
Joined: 11 Apr 2017 06:17
Location: Italy

Re: CRC16 functions

#5 Post by cgengineer » 30 May 2017 11:26

Obrigado!

This library is completely free for commercial, hobby, space, medical, military, nuclear plants, warping astroships and alien gunboats... so enjoy!

Best

belko
Posts: 1
Joined: 27 Jul 2010 12:59

Re: CRC16 functions

#6 Post by belko » 29 Dec 2018 19:07

Hello,
It is much easier to calculate the CRC for an array of byte variables.
And this routine uses much less software space.

// Function of calculation CRC (CRC-16-IBM)
/****************************************************************************
Function parameters:
Input:
buf -> Pointer to an array of type char for which you want to calculate the CRC.
cnt -> Number of array elements
Output:
temp -> CRC (unsigned int).
COMMENTS:
Used polynomial coefficient - 0xA001.
****************************************************************************/

unsigned int crc(char *buf, char cnt)
{
char i, jj;
unsigned int temp;

temp = 0xFFFF; // Initial state of the shift register
for (i = 0; i < cnt; i++)
{ Lo(temp) ^= buf;
for (jj = 0; jj < 8; jj++)
{ if (Lo(temp).B0) temp = (temp >> 1) ^ 0xA001;
else temp = temp >> 1;
}
}
return temp;
}

Post Reply

Return to “mikroC PRO for PIC Beta Testing”