CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

crc 16 calculation help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
[email protected]



Joined: 28 Jul 2014
Posts: 38

View user's profile Send private message

crc 16 calculation help
PostPosted: Tue Dec 15, 2020 4:20 am     Reply with quote

I am using dspic33ep512mu810.
I am new to CRC kindly guide me how to calculate 16bit crc
for example the Modbus RTU data is
01 05 00 02 FF 00
and CRC for the above is 2D FA

CASE 1: 01 05 00 02 FF 00 how to get 2D FA (generate crc)

CASE 2: how to check 2D FA is correct for 01 05 00 02 FF 00 ( check crc)
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Tue Dec 15, 2020 4:33 am     Reply with quote

If you look in the example physical layer. Modbus_phy_layer_rtu.c
it has a function modbus_calc_crc, that will calculate the CRC if called with
the data bytes one by one. You need to start the CRC set to 0xffff before
calling the first time. It does it quickly by using table look ups for the values.
By far the fastest and easiest way to do this.
You calculate the CRC as you receive the bytes, and then compare this
with what you receive for the CRC bytes.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Tue Dec 15, 2020 9:56 am     Reply with quote

Hello,

Here is sample test program for your example packet and how to setup serial port of this controller:
Code:

#include <33EP512MU810.h>
#device ICSP=1
#use delay(crystal=8MHz, clock=16MHz)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOJTAG                   //JTAG disabled

/* HW UART1 */
#pin_select U1RX=PIN_E1         // Rx Com1.
#pin_select U1TX=PIN_E0         // Tx Com1.   
#define EN1_485 PIN_D1          // RE/DE Com1.

#use rs232(UART1,baud=9600,errors)

const unsigned int16 wCRCTable[] = {
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

unsigned int16 CRC16 (BYTE *nData, unsigned int16  wLength){
   BYTE nTemp;
   unsigned int16  wCRCWord = 0xFFFF;

   while (wLength--)
   {
      nTemp = *nData++ ^ wCRCWord;
      wCRCWord >>= 8;
      wCRCWord ^= wCRCTable[nTemp];
   }
   return wCRCWord;
}

void main(void){

   delay_ms(1000); // some starup delay
   
   printf("\r\n ModBus RTU CRC Example.\r\n");
   
   unsigned int16 CalcW_CRC = 0;
   unsigned int16 RecW_CRC = 0xFA2D; // MSB,LSB swapped!
   
   BYTE data[] = {0x01,0x05,0x00,0x02,0xFF,0x00}; // 0x2DFA - Received wCRC sum.
   
   CalcW_CRC = CRC16(data, sizeof(data));  //
   
   printf("\r\n Recived CRC=0x%lX, Calc.CRC=0x%lX",RecW_CRC, CalcW_CRC);
   
   if(CalcW_CRC == RecW_CRC)
      printf("\r\n CRC-OK!");
   else
      printf("\r\n CRC-ERROR!");
   
   while(TRUE){
   
      //User Code ...
   }   
}


Best Regards,
steve__p



Joined: 09 Sep 2020
Posts: 2

View user's profile Send private message

PostPosted: Tue Dec 15, 2020 11:33 am     Reply with quote

For your info, here is my version without table, used with PIC24FJ128GA306:

Code:

uint16 modbus_crc(uint8 *data,uint8 size)
{
   uint16   crc;
   uint8    i,z;
   
   crc=0xFFFF;
   for(i=0;i<size;i++)
   {
      crc=crc^data[i];
      for(z=0;z<8;z++)
      {
         if(bit_test(crc,0))
         {
            crc=crc/2;
            crc=crc^0xA001;
         }
         else crc=crc/2;
      }
   }
   return(crc);
}
[email protected]



Joined: 28 Jul 2014
Posts: 38

View user's profile Send private message

PostPosted: Tue Dec 15, 2020 11:33 pm     Reply with quote

kmp84 wrote:
Hello,

Here is sample test program for your example packet and how to setup serial port of this controller:
.
.
.


your code works great thanks for the help bro.
i have one doubt, what is the maximum number of bytes i can check.
wlength=?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Wed Dec 16, 2020 2:10 am     Reply with quote

Potentially 32KB!....

wlength is an int16, which on a PIC24/33 is a signed int16, so maximum
supported length would be 32767 bytes, However obviously real limits on how
much data you can actually store would override this. Modbus itself limits
the maximum packet size.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Wed Dec 16, 2020 4:20 am     Reply with quote

Hi,

Here is Modbus specification:
https://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf

I think max. data field length are 125 registers x 2 bytes =250 bytes, but read info from link above. It's also depend from external factors like line length, baud rate if using rs485 interface etc.

P.S. CCS's modbus rtu driver work very well for me, but when packets are long they don't use transmit interrupts! I don't know why.Rolling Eyes

Best Regards!
[email protected]



Joined: 28 Jul 2014
Posts: 38

View user's profile Send private message

PostPosted: Thu Dec 17, 2020 3:42 am     Reply with quote

sir where can i find CCS's modbus rtu driver?
any link ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu Dec 17, 2020 3:56 am     Reply with quote

It is with the compiler.

Sub-directories of the the compiler directory. Examples, and drivers.
There is a master and slave modbus example. The physical hardware driver
changes for RTU, and is modbus_phy_layer_rtu.c This is automatically
loaded if you specify the MODBUS_SERIAL_TYPE as MODBUS_RTU.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group