Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] CRC code generation problem

Status
Not open for further replies.

AliBahar

Member level 2
Joined
Feb 4, 2015
Messages
42
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
337
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)
• Discard Q, keep R
• 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)
Untitled.jpg
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:

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

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:

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 ?
 

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.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top