# [SOLVED]CRC code generation problem

Status
Not open for further replies.

#### AliBahar

##### Member level 2
Hi friends
for DNP3 protocol crc code is generated by the following algorithm:
• Start with user data block M of k bits (k = 64 for header, 8–128 for blocks in body)
• Multiply by 65536 (ie append 16 zeros to end to form k + 16-bit number)
• Divide by generator polynomial P to obtain quotient Q and remainder R modulo-2 division is used)
• Invert R to obtain R′
• Append R′ to M forming message T′ to be transmitted
Where generator polynomial:
P = x16 + x13 + x12 + x10 + x8 + x5 + x2 + 1
This forms a 17-bit number which is 13D65 (in hex)

now I have created the following C code for crc generation. but the result is not correct:

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include "stdio.h"
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long int UL;

#define WIDTH  (8 * sizeof(UL))
#define TOPBIT (1 << (WIDTH - 1))
UL POLYNOMIAL=0x3D650000;
uint  remainder = 0;

uint crcGener(uint *message, uchar nSize)
{
uchar ff, bit;
UL Rem;
Rem=message[0]<<16;

for (ff = 1; ff < nSize; ff++){
Rem ^=message[ff];
//printf("%x\n",Rem);
for (bit = 0; bit <16; ++bit)
{

if (Rem & TOPBIT)
{
Rem = (Rem << 1) ^ POLYNOMIAL;
}
else
{
Rem = (Rem << 1);
}
}

}

/*
* The final remainder is the CRC result.
*/
return (Rem>>16);

}

void main(void){
uint Msg[5]={0x0564,0x0DC4,0x0500,0x1A00,0x0000};

remainder=crcGener(Msg, 5);
//printf("%x\n",remainder);
getchar();
}

Last edited:

#### Easyrider83

Code:
unsigned char Crc8Dallas(unsigned char len, unsigned char *pData)
{
unsigned char crc = 0;
unsigned char i;

while (len--)
{
crc ^= *pData++;
for (i = 0; i < 8; i++)
crc = crc & 0x01 ? (crc >> 1) ^ 0x8C : crc >> 1;
}
return crc;
}

unsigned char Crc8(unsigned int len, unsigned char *pcBlock)
{
unsigned char crc = 0xFF;
unsigned int i;

while (len--)
{
crc ^= *pcBlock++;
for (i = 0; i < 8; i++)
crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
}
return crc;
}

#### AliBahar

##### Member level 2
thanks for response
but the length of crc must be 16 bit. the polynomial value is constant number :0x13D65. there are several methods for performing crc calculation. I must do it based on indicated method.
the message is divided by polynomial using modulo-2 division. the crc is obtained from inversion of remainder.

Last edited:

#### andre_teprom

##### Super Moderator
Staff member
I did´t perform a deep analysis of your code, but at the line 17, the variable ff shouldn´t start from 0, instead of 1 ?

#### AliBahar

##### Member level 2
at the line 17, the variable ff shouldn´t start from 0, instead of 1 ?
at the line 15, the first element of message (message[0]) is appended to Rem.

Status
Not open for further replies.