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.

[General] CRC function in Modbus protocol

Status
Not open for further replies.

uplifting_mind

Newbie level 6
Joined
May 7, 2013
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Slovakia
Activity points
1,359
Hello,

I trying to make program for building and sending Modbus RTU packet. Program contain a function for CRC. Results of CRC must be two bytes placed in the end of packet. This is what I have yet, there is function for CRC and function send_packet(), which I call from main. But there is some error during compilation. I don´t know how to forward my packet[] array to CRC function. I don´t understand pointers very well.

Please help.

Code:
uint8_t packet[5];
int i;
int len;
uint16_t crc;
uint8_t crc_LByte;
uint8_t crc_HByte;
uint8_t *buf;
uint8_t pos;

// Compute the MODBUS RTU CRC
uint16_t ModRTU_CRC(uint8_t *buf, int len)
{
  uint16_t crc = 0xFFFF;
 
  for (int pos = 0; pos < len; pos++) {
    crc ^= (uint16_t)*buf[pos];          // XOR byte into least sig. byte of crc
 
    for (int i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return crc;  
}

void send_packet(uint8_t address, uint8_t function, uint8_t lo_data, uint8_t hi_data) {

packet[0] = address;  // build packet
packet[1] = function;
packet[2] = lo_data;
packet[3] = hi_data;
	
    crc = ModRTU_CRC(packet, 4);
    crc_LByte = (crc & 0x00FF); // Low byte calculation
    crc_HByte = (crc & 0xFF00) / 256; // High byte calculation 

packet[4] = crc_LByte;
packet[5] = crc_HByte;
	
    for (i = 0; i < 6; i++) {
    printf("%d %02x\n", i, (int) packet[i]);    // send packet
    } 
}
 

You forgot to mark the error line.

I guess you have an error in this line
Code:
crc ^= (uint16_t)*buf[pos];

You should try
Code:
crc ^= buf[pos];
 

    V

    Points: 2
    Helpful Answer Positive Rating
Pointer is a just a phisical address of first element in array.
buf[pos] is equal to *but+pos
 

In the lines

Code:
for (int pos = 0; pos < len; pos++) {

and

Code:
for (int i = 8; i != 0; i--) {

is still error "expected an expression".
 

Hello,

I trying to make program for building and sending Modbus RTU packet. Program contain a function for CRC. Results of CRC must be two bytes placed in the end of packet. This is what I have yet, there is function for CRC and function send_packet(), which I call from main. But there is some error during compilation. I don´t know how to forward my packet[] array to CRC function. I don´t understand pointers very well.

Please help.

Code:
uint8_t packet[5];
int i;
int len;
uint16_t crc;
uint8_t crc_LByte;
uint8_t crc_HByte;
uint8_t *buf;
uint8_t pos;

// Compute the MODBUS RTU CRC
uint16_t ModRTU_CRC(uint8_t *buf, int len)
{
  uint16_t crc = 0xFFFF;
 
  for (int pos = 0; pos < len; pos++) {
    crc ^= (uint16_t)*buf[pos];          // XOR byte into least sig. byte of crc
 
    for (int i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
  return crc;  
}

void send_packet(uint8_t address, uint8_t function, uint8_t lo_data, uint8_t hi_data) {

packet[0] = address;  // build packet
packet[1] = function;
packet[2] = lo_data;
packet[3] = hi_data;
	
    crc = ModRTU_CRC(packet, 4);
    crc_LByte = (crc & 0x00FF); // Low byte calculation
    crc_HByte = (crc & 0xFF00) / 256; // High byte calculation 

packet[4] = crc_LByte;
packet[5] = crc_HByte;
	
    for (i = 0; i < 6; i++) {
    printf("%d %02x\n", i, (int) packet[i]);    // send packet
    } 
}

unsigned int modbuscrc(unsigned char *buf,int len)
{
unsigned int crc = 0xffff;
int pos;
for (pos = 0; pos < len; pos++)
{
crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc

for (int i = 8; i>0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}


return crc;
}


it is compiling like this.

- - - Updated - - -

I have a question also. maybe it will be a stupid question :)

with0x00 data.jpgwith0x01.jpg

void main(void)
{
setISR();
setRS();
buffer[0]=0x01; //slave address
buffer[1]=0b00000011; //function code
buffer[2]=0x00; //address low if i use 0x01 it is transmitting all data. if 0x00 it is not why? this is my qustion
buffer[3]=0x01; //address high
buffer[4]=0x02; //just for try crc generation changes
buffer[5]=0x02; //just for try crc generation changes
crc16(buffer,6); // creats crc and add it to the buffer 6 and 7.
__delay_ms(600);
writemdframe(buffer);
while (1)
{
}
}


void writemdframe(unsigned char *str)
{
while((*str)!=0)
{
writeRS(*str);
str++;
}
}
void writeRS(unsigned char c)
{
TXREG = c;
TXEN = 1;
while (!TRMT);
}
 
Last edited:

In the lines


Code:
for (int pos = 0; pos < len; pos++) {and


Code:
for (int i = 8; i != 0; i--) {is still error "expected an expression".
I presume, the compiler doesn't support the c++ variable definition style inside for( ).
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top