Question

i want to send some bytes via RS232 to a DSPIC33F that controls a robot motors, the DSPIC must receive 9 bytes orderly the last 2 bytes are for CRC16, am working in C#, so how can i calculate the CRC bytes meant to be sent.

the program that calculates the CRC16, i have found it in the internet :

using System;
using System.Collections.Generic;
using System.Text;

namespace SerialPortTerminal
{
public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }

public class Crc16Ccitt
{
    const ushort poly = 4129;
    ushort[] table = new ushort[256];
    ushort initialValue = 0;

    public ushort ComputeChecksum(byte[] bytes)
    {
        ushort crc = this.initialValue;
        for (int i = 0; i < bytes.Length; i++)
        {
            crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
        }
        return crc;
    }

    public byte[] ComputeChecksumBytes(byte[] bytes)
    {
        ushort crc = ComputeChecksum(bytes);
        return new byte[] { (byte)(crc >> 8), (byte)(crc & 0x00ff) };
    }

    public Crc16Ccitt(InitialCrcValue initialValue)
    {
        this.initialValue = (ushort)initialValue;
        ushort temp, a;
        for (int i = 0; i < table.Length; i++)
        {
            temp = 0;
            a = (ushort)(i << 8);
            for (int j = 0; j < 8; j++)
            {
                if (((temp ^ a) & 0x8000) != 0)
                {
                    temp = (ushort)((temp << 1) ^ poly);
                }
                else
                {
                    temp <<= 1;
                }
                a <<= 1;
            }
            table[i] = temp;
        }
    }
}
}
Was it helpful?

Solution

With the class you provided you would create the buffer of data that you want:

byte[] data = new byte[7];
data[0] = 1;    // This example is just random numbers
data[1] = 12;
data[2] = 17;
data[3] = 9;
data[4] = 106;
data[5] = 12;
data[6] = 0;

Then calculate the checksum bytes:

Crc16Ccitt calculator = new Crc16Ccitt();
byte[] checksum = calculator.ComputeChecksumBytes(data);

Then either write the two parts of the data

port.Write(data);
port.Write(checksum);

Or build a packet to be written from the two parts:

byte[] finalData = new byte[9];
Buffer.BlockCopy(data, 0, finalData, 0, 7);
Buffer.BlockCopy(data, 7, checksum, 0, 2);
port.Write(finalData);

The class you've posted could be rewritten slightly to make it a bit more efficient and easier/cleaner to use but it should suffice as long as it calculates the CRC 16 in the same way as the device you're communicating with. If this doesn't work then you need to consult the documentation for the device, or ask the manufacturer for the details you need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top