MODBUS Communication Problem

S

Thread Starter

Sandip

Dear Friends,

I m trying to communicate LPC2148 microcontroler with Schneider M340 PLC over MODBUS RTU. I have pasted my program here. My problem is PLC is not getting any thing.

Need your valuable guidance.<pre>
#include <LPC214X.H>
#include <stdlib.h>

long GetCRC(void);
void init_uart(void);
void transfer_485( unsigned char Data[]);
void tx_CRC(unsigned char);
unsigned char arr[]={'1' , '6' , '0', '0' , '0' , '2' };
//int arr1[]={1,6,0,2,0,78};
long a;
unsigned char j1;
int main()
{
VPBDIV=0X00;
PINSEL0=0X00000005; //P0.0 & P0.1 CONFIGURE FOR TX AND RX
PINSEL1=0X00000000; //PIN P0.30 /RE AND P0.31 DE AS GPIO

/*IO0DIR=0X00FF0000;*/

init_uart(); //INITIALIZESD THE UART

while(1)
{
transfer_485(arr);

}


}

/*ROUTINE FOR INITILIZATION OF UART0*/
void init_uart()
{
U0FCR=0X07; //BOTH TX AND RX FIFO DISABLE
U0LCR=0X8b; //DLAB BIT ENABLE,PARITY ENABLE,1 STOP BIT,8 DATA BITS
U0DLL=97; //VALUE TO GENERATE 9600 BDR
U0LCR=0X0b; //DLAB BIT DISABLE

}
/*ROUTINE FOR TRASMISSION OF DATA*/
void tx(unsigned char ch)
{
char d1,d2,d3,temp;
d1=ch-'0';
d2=d1<<4;
d3=d1>>4 ;
temp=d2 | d3;
while((U0LSR & 0X40)==0);
U0THR=temp;
//THRE is set immediately upon detection of an empty UART0 THR
//WRITE DATA TO TRASMIT HOLDING REGISTER
}
/*ROUTINE FOR TRASMISSION OVER RS485 */
void transfer_485( unsigned char Data[])
{
unsigned char i1;
unsigned char CRC_HI,CRC_LO;
unsigned int time;
IO0DIR=0XC0ff0000; //Select the direction of p0.30,p0.31 as OP
IO0SET=0xC0000000; //p0.30=/RE,p0.31=DE both are high for transmission
a = GetCRC();
CRC_HI=a;
CRC_LO=a>>8;
/*U0LCR |=0x2b; //from init_uart LCR=0x0000 1011*/
for(time=0;time<=10000;time++);
for(i1=0;i1<6;i1++)
{
unsigned char Snd_Data;
Snd_Data=Data[i1];
tx(Snd_Data);
for(time=0;time<=5000;time++);
}
tx_CRC(CRC_HI);
for(time=0;time<=5000;time++);
tx_CRC(CRC_LO);
for(time=0;time<=10000;time++);
}

/*GENERATING CRC FROM TRASMISSION DATA*/
long GetCRC(void)
{
long CRCValue=0xffff;
long MLength;
int i,j,Data1;

char Data;
for (i=0;i<6;i++)
{
Data = arr;
Data1 = Data-'0';
CRCValue = CRCValue ^ Data1 ;
for(j=0;j<8;j++)
{
MLength = (CRCValue & 1) ;
CRCValue = (CRCValue / 2);
if(MLength & 0x01)
{
CRCValue = CRCValue ^ 40961 ;
}//end if
}//for 2
} //for 1
return(CRCValue);
}

void tx_CRC(unsigned char ch1)
{
char d2,d3,temp;
d2=ch1<<4;
d3=ch1>>4 ;
temp=d2 | d3;

U0THR=temp;
while((U0LSR & 0X40)==0); //THRE is set immediately upon detection of an empty UART0 THR
//WRITE DATA TO TRASMIT HOLDING REGISTER
}</pre>
 

> I m trying to communicate LPC2148 microcontroler with Schneider M340 PLC over MODBUS RTU. I have pasted my program
> here. My problem is PLC is not getting any thing.

This is a common problem/situation, you set things up, send out a message, and... nothing...

Do yourself a favor and disconnect the PLC and send the same message out to a PC running a terminal program (I like RealTerm).

Get whatever is sees and look to see what you are missing (or have inadvertently added).

Since you are using RTU, you have timing to consider as well. So if your string checks out in a terminal program, then it's time to break out the logic analyzer and check to see if your are adhering to the timing spec.

From http://www.modbus.org/docs/Modbus_over_serial_line_V1.pdf

"The implementation of RTU reception driver may imply the management of a lot of interruptions due to the t1.5 and t3.5 timers. With high communication baud rates, this leads to a heavy CPU load. Consequently these two timers must be strictly respected when the baud rate is equal or lower than 19200 Bps. For baud rates greater than 19200 Bps, fixed values for the 2 timers should be used: it is recommended to use a value of 750µs for the inter-character time-out (t1.5) and a value of 1.750ms for inter-frame delay (t3.5)."

I'm no C programmer, but your timing routine looks questionable.
 
Top