Dear all ,
I am implimenting modbus RTU in c on atmega328. I am sharing part of code. Below code work fine for function 3. But i get checksome error for response for function code1.
I have make ensure CRC function is working well with below code. But sending modbus response i get an error.
I have attached Screen shot of request/response from slave device.
crc calculation:
CRC function
unsigned int crc_fn(unsigned char *dpacket,unsigned int len) // CRC Function(Error calcualtion)
{
unsigned int crc = 0xffff,poly = 0xa001;
unsigned int i=0;
for(i=0;i<len;i++)
{
crc^= dpacket[i];
for(j=0;j<8;j++)
{
if(crc & 0x01)
{
crc >>= 1;
crc ^= poly;
}
else
crc >>= 1;
}
}
return (crc);
}
Serial_data () i am calling in timer interrupt Below code for Function 1
void Serial_Data()
{
unsigned int address,crc1,crc2;
unsigned char length,i;
unsigned char Data_Len_Count;
unsigned char length1;
// Serial_1_Send_byte(rxbuf[0]);
crc2=crc_fn(&rxbuf[0],6); //crc function for received protocol from request
__delay_ms(10); // Changed on 20.01.2017
if((rxbuf[6]==(unsigned char)(crc2))&&(rxbuf[7]==((unsigned char)(crc2>>8))))
{
if(rxbuf[0]==Device_ID )
{
if(rxbuf[1]==READ_REG)
{
address=(((unsigned int)(rxbuf[2]<<8))+((unsigned int)(rxbuf[3])));
if(rxbuf[5]>=1)
{
length1=(rxbuf[5]<249)?(rxbuf[5]+7)/8:0X20;
length=(rxbuf[5]*1);
address=(address*1);
ser_data[0]=Device_ID ;
ser_data[1]=rxbuf[1];
ser_data[2]=length;
ser_data[3]=rxbuf[6];
ser_data[4]=rxbuf[7];
ser_data[5]=length1;
ser_data[6]=00;
ser_data[7]=00;
ser_data[8]=00;
ser_data[9]=00;
crc_data[0]=Device_ID ;
crc_data[1]=rxbuf[1];
crc_data[2]=length;
j=3;
for(i=address;i<((address+length));i++)
{
crc_data[j++]=ser_data[i+3];
// ChecksumCal(length);
}
crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device
Serial_1_Send_byte(ser_data[0]);
Serial_1_Send_byte(rxbuf[1]);
Serial_1_Send_byte(ser_data[2]);
for(i=address;i<((address+length));i++)
{
Serial_1_Send_byte(ser_data[i+3]);
}
Serial_1_Send_byte((unsigned char)crc1);
Serial_1_Send_byte((unsigned char)(crc1>>8));
Serial_1_Send_byte(crc_msb);
Serial_1_Send_byte(crc_lsb);
for(i=0;i<30;i++)
{
Serial_1_Send_byte(0);
}
}
}
__delay_ms(5);
}
}
index=0;
rec_flag = 0;
}
I am suspecting on below parts ,
- moving the data into serial buf
2)calculating length of coil.
crc_data[0]=Device_ID ;
crc_data[1]=rxbuf[1];
crc_data[2]=length;
j=3;
for(i=address;i<((address+length));i++)
{
crc_data[j++]=ser_data[i+3];
// ChecksumCal(length);
}
crc1 =crc_fn(&crc_data[0],(length+3)); //crc function for response protocol from the device
Serial_1_Send_byte(ser_data[0]);
Serial_1_Send_byte(rxbuf[1]);
Serial_1_Send_byte(ser_data[2]);
for(i=address;i<((address+length));i++)
{
Serial_1_Send_byte(ser_data[i+3]);
}
Serial_1_Send_byte((unsigned char)crc1);
Serial_1_Send_byte((unsigned char)(crc1>>8));
function code1: http://dghcorp.com/modbus/modbusrtu01.asp
Data HI 7C - Data Coils (17-10) Status
Data LO 03 - Data Coils (19-18) Status
function code 3:http://dghcorp.com/modbus/modbusrtu03.asp
Data HI 7C - Data Register HI Byte
Data LO 93 - Data Register LO Byte
Can someone suggest me what changes can be done to make work on function 1