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.

CRC calculations of ASCII code

Status
Not open for further replies.

cool.man

Full Member level 6
Joined
May 29, 2008
Messages
323
Helped
42
Reputation
84
Reaction score
29
Trophy points
1,308
Location
Earth
Activity points
3,307
Hi Guys
I am working on some project and want to communicate microcontroller with the device.
Commands will be send through the device.
for example the command I send will be
ASCII code CRC-2.png

it will calculate CRC internally and be like that
ASCII code CRC.png

Here CRC are (AB and m6D).

I want to know how to calculate CRC of the commands.
Kindly guide me

Thanks
 

Attachments

  • ASCII code CRC-2.png
    ASCII code CRC-2.png
    2.4 KB · Views: 138

There are a number of CRC algorithms so firstly you need to either know which algorithm the receiving end will be expecting, or you can determine this for yourself.
Once you have this sorted, then it doesn't really matter what input data you are using - the algorithm just takes in values and spits out the CRC.
What can matter is if the CRC algorithm expects 8, 16, 32 (or some other number) of bits to the input values. But whether those values are ASCII character, binary numbers, EBCDIC etc. doesn't really matter.
Susan
 

Dear @Aussie Susan Thanks for your reply.
Could you tell me how many types of algorithm are there? How to identify this?

I have received the CRC routine from vender side. Could you tell me about this.

Code:
INT16U cal_crc_half(INT8U far *pin, INT8U len)
{
    INT16U crc;
    INT8U da;
    INT8U far *ptr;
    INT8U bCRCHign;
    INT8U bCRCLow;

    INT16U crc_ta[16] = { 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef};
    ptr=pin;
    crc=0;
    len--;
    while(len--!=0)
    {
        da=((INT8U)(crc>>8))>>4;
        crc<<=4;
        crc^=crc_ta[da^(*ptr>>4)];
        da=((INT8U)(crc>>8))>>4;
        crc<<=4;
        crc^=crc_ta[da^(*ptr&0x0f)];
        ptr++;
    }
    bCRCLow = crc;
        bCRCHign= (INT8U)(crc>>8);

    if(bCRCLow==0x28||bCRCLow==0x0d||bCRCLow==0x0a)
    {
        bCRCLow++;
    }

    if(bCRCHign==0x28||bCRCHign==0x0d||bCRCHign==0x0a)
    {
    bCRCHign++;
    }

    crc = ((INT16U)bCRCHign)<<8;
    crc += bCRCLow;
    return(crc);
}
 

Apparently CRC-16-CCITT, with arbitrary modification. Due to the modification, the CRC is no longer unique and can't be checked by simply sending the stream with appended CRC to the CRC algorithm.

Also arbitrary, the code expects a len value of 8 to calculate the CRC of 7 bytes.
 

@FvM dear then how I understand this code. How it is working and then to implement this in my microcontroller
 

The code is more or less working as expected for a CRC calculation function.
C:
typedef unsigned char INT8U;
typedef unsigned short INT16U;
unsigned char str[] = "^P003ID";
unsigned short crc;
crc = cal_crc_half(str, 8);
// gives crc = 0xAB6D
 

@FvM Thanks dear for your response.
I tried the code and it seems ok to me.
The tool which they send me have the same response as of my microcontroller program.
for example if I send command ^P003ID from their tool then the CRC is AB 6D.
P003ID.png


and response of microcontroller is also AB 6D

if I send command ^P005ID from their tool then the CRC is 19 CD
P005ID.png

and response of microcontroller is also 19 CD.
I think function is working fine.

one question I have in mind. Here I am declaring char array for command
Code:
unsigned char command_send[] = "^P005ID";

but in the function it is treating as an 8bit integer with a pointer
Code:
unsigned int16 cal_crc_half(unsigned int *pin, unsigned int len)

Kindly explain this. How it is working

Thanks
 

Hi,

An array is referenced with a pointer.
And a char is a 8 bit integer.
So technically both are identical.

A CHAR just tells the compiler that the value is expected to be an ASCII character.
An INT is treated as a number 0..255 (or -128...0...+127) that you can calculate with (add, multiply...)

In the end it does not matter, 8 bits are 8 bits.

Klaus
 

but in the function it is treating as an 8bit integer with a pointer
Code:
unsigned int16 cal_crc_half(unsigned int *pin, unsigned int len)
In the code you have posted, *pin is a pointer to 8 bit unsigned data, indicated by the user declared type INT8U. The size of int is target respectively compiler dependent. A few 8 bit compilers have a default int size of 8 bits, most 8 and 16 bit compilers are defining int as 16 bit entity, 32 bit compilers generally as 32 bit.

Even if a compiler has default int size of 8 bit, I would strictly avoid it in declaration of 8 bit entities. Better use char, short and long, respectively non-ambigous types provided by the respective compiler like int8, int16 and int32.
and what it is going on. (*ptr>>4)
Suggest to read a C text book, e.g. Kernighan/Ritchie, the C Programming Language.

*ptr is one byte of the input string, >>4 is a logic right shift, in case of byte data, the upper 4 bits ("nibble") are shifted into the position of the lower nibble, the original lower nibble is discarded. It's part of the CRC algorithm, there are slow single bit variants, and faster table based 4 and 8 bit variants. This is a medium fast 4 bit variant.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top