## CRC-16 Calculation

January 16, 20138 comments Coded in C

This code is the function that calculates a CRC-16 for different purposes. The function requires a POLYNOM from the CRC-16 type.

``````/***** crc16.h *****/
//Tested
#define CRC16_DNP	0x3D65		// DNP, IEC 870, M-BUS, wM-BUS, ...
#define CRC16_CCITT	0x1021		// X.25, V.41, HDLC FCS, Bluetooth, ...

//Other polynoms not tested
#define CRC16_IBM	0x8005		// ModBus, USB, Bisync, CRC-16, CRC-16-ANSI, ...
#define CRC16_T10_DIF	0x8BB7		// SCSI DIF
#define CRC16_DECT	0x0589		// Cordeless Telephones
#define CRC16_ARINC	0xA02B		// ACARS Aplications

#define POLYNOM		CRC16_XXX   // Define the used polynom from one of the aboves

// It calculates the new crc16 with the newByte. Variable crcValue is the actual or initial value (0).
unsigned int crc16(unsigned int crcValue, unsigned char newByte);

/***** crc16.c *****/

#include "crc16.h"

unsigned int crc16(unsigned int crcValue, unsigned char newByte)
{
unsigned char i;

for (i = 0; i < 8; i++) {

if (((crcValue & 0x8000) >> 8) ^ (newByte & 0x80)){
crcValue = (crcValue << 1)  ^ POLYNOM;
}else{
crcValue = (crcValue << 1);
}

newByte <<= 1;
}

return crcValue;
}

/***** EXAMPLE *****/

unsigned int exampleOfUseCRC16 (unsigned char *Data, usigned char len){

unsigned int crc;
unsigned char aux = 0;

crc = 0x0000; //Initialization of crc to 0x0000 for DNP
//crc = 0xFFFF; //Initialization of crc to 0xFFFF for CCITT

while (aux < len){
crc = crc16(crc,Data[aux]);
aux++;
}

return (~crc); //The crc value for DNP it is obtained by NOT operation

//return crc; //The crc value for CCITT
}``````

stephaneb
Said:
Maykel, is this code specifically for the MSP430? (same question applies to the Fifo snippet). Also, there is a typo in the description (function). Thanks.
7 years ago
0
Sorry, you need javascript enabled to post any comments.
Maykel
Said:
All the snippets I could upload works in the MSP430, but they should work for other Processors, so I have changed both.
7 years ago
0
Sorry, you need javascript enabled to post any comments.
weber_cs
Said:
What the hell are you doing? Earning money by uploading code snippets? It makes me fear if I read about your special interest field "... inside human bodies". Perhaps you should do something more with the newByte when calculating the checksum. Unfortunately I cannot rate this code with 0 stars.
7 years ago
-4
Sorry, you need javascript enabled to post any comments.
Cryptoman
Said:
This code looks like it has been provided in a rush without any review or verification. The newByte <<= 1; statement has no use in this code. So what is it doing there? Also, CRC16 calculations require that the shift register is initialised with a non-zero 16-bit value. I cannot see any of that initialisation here. For CCITT-CRC16, the initialisation with the 0xFFFF vector is critically important as that is a part of the accepted standard. There is more to CRC calculations than just a polynomial. To prove my point, you can test the CCITT-CRC16 polynomial with the following reference input vector (of 15 bytes) and I bet you will not get the expected output with this code. input vector: 0x06 0x00 0x0c 0xf0 0x00 0x04 0x00 0x55 0x88 0x73 0xc9 0x00 0x00 0x05 0x21 expected CCITT output: 0x75FB Internet is filled with similar code snippets on CRC16 and the funny thing is they all give different results for the same input vector! Obviously, come CRC16 results are more correct than others :) :)
7 years ago
0
Sorry, you need javascript enabled to post any comments.
Maykel
Said:
Hello Cryptoman, I added for you an example of use of the code, I do use for M-BUS and it works perfectly. For other polynoms I don't know if it works, but I will try to check them.
7 years ago
-1
Sorry, you need javascript enabled to post any comments.
Maykel
Said:
Hello again, I tested CCITT polynom and works great but with initialisation with 0xFFFF.
7 years ago
+2