You are on page 1of 3

Appendix B

Cyclic redundancy check


(CRC) program listing

#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef DAT // to avoid multiple definitions due to order


#define DAT // of #includes
struct dat // this is a data structure used for passing between objects
{
int addr, // address of device
fcn, // number of function
dcount, // number of elements in data
crc; // crc check code
char *data; // pointer to data
};
#endif

static unsigned CRC16=0xA001; // Polynomial used for CRC-16 checksum

union doub { // union for CRC check


unsigned i; // as an unsigned word
char c[2]; // as two characters
struct bits{ // as a bitfield
332Practical Data Communications for Instrumentation and Control

unsigned msb:1; // most significant bit


unsigned:14;
unsigned lsb:1; // least significant bit
} b;
};

void whatcrc(struct dat *d, int mode) // calculate a CRC given a dat structure
{
char *msg; // buffer to message
int i,j,len; // counters and length of message
union doub sck,byt;

len=(mode?2:0)+2+(d->dcount); // calculate length (data is the only field


without fixed length)
msg = (char *)malloc(len); // allocate space for message buffer
if (!msg) // didn't happen? Say so and quit.

{
printf("Sorry, but I couldn't allocate memory\n");
exit(1);
}

// Load the msg buffer


msg[0]=d->addr; // load the addr field as byte 1
msg[1]=d->fcn; // load the fcn field as byte 2

for (i=0;i<d->dcount;++i)
msg[i+2]=d->data[i];

if (mode)
{
msg[i+2]=(d->crc&0xFF00)>>8;
msg[i+3]=d->crc&0x00FF;
}

// CRC check algorithm live!

sck.i=0xFFFF; // set initial remainder


for (i=0;i<len;++i) // for each byte in buffer
Appendix B – CRC listing 333

{
byt.c[0]=msg[i]; // put the current character at end of working byt
byt.c[1]=0; // set start of byt to 0
sck.i^=byt.i; // set sck to sck XOR byt (MOD-2 maths)
for (j=0;j<8;++j) // for each bit
{
if (sck.b.msb)
{
sck.i>>=1; // shift the remainder right 1 bit
(divide by 2)
sck.b.lsb=0; // and set the MSB to 0
sck.i^=CRC16; // set remainder = sck XOR the CRC16
polynomial
}
else
{
sck.i>>=1; // shift the remainder right 1 bit
(divide by 2)
sck.b.lsb=0; // and set the MSB to 0
}
}
}
d->crc = (sck.i)<<8; // update the CRC in the data structure
d->crc |= (sck.i&0xFF00)>>8;
free (msg); // free the temporary storage area
}

You might also like