Discussion in "8051 Discussion Forum" started by    Karan123    Jun 11, 2016.
Sat Jun 11 2016, 10:42 AM
#1
Hi,


I have worked on UART RS232 from long time . Now I got project Long Distance(100 Meter) Multi-point Communication. I have chosen with RS-485 Protocol.

I have made a system with AT89S52 and sn75176 (MAX487) as below:

1) One Master IC with sn75176
2) Four Slave ICs with sn75176

One Master should communicate four slaves.

I am attaching Circuit . Are my code(s) are below. I am not getting proper as per program.

// Code Master
#include<reg51.h>



sfr  SEG7_2 = 0x80  ;    // PORT 0
sbit SELECT = P3^2 ;
sbit SW= P3^3 ;

#define TRANSMIT  1
#define RECEVICE  0


void InitSerialInterrupt()     ;

char i,k ;

void DelayMs(unsigned int period)
{
		int i,j;
		for(i=0;i<period;i++)
				for(j=0;j<250;j++);	
} 
// This for initializing serial terminal
void InitSerialInterruptRS485() 
{
  TMOD  = 0x20; 	 	  // Timer 0 Mode One
	TH1   = 0xFD;				// Baud Rate 9600
	SCON  = 0x50;	  	// Receive Transmit Enable
	TR1 = 1;		  		// Timer Run
	EA  = 1;	          	// Enable Global Interrupt
	ES  = 1;			  			// Enable Serial Interrupt
	RI  = 0;				      // Clear RI Interrupt
	TI  = 0;             // Clear TT Interrupt 
}
// For interrupt handler
void Seiintr() interrupt 4		
{

	if(TI==1)
	{
		TI=0;
	}				 
	else		
	{
		 RI = 0;
	}
}
// This function will send any string to Hyper Terminal
void SerialString(unsigned char *temp)
{
	while(*temp)
	{
		SBUF = *temp;
		DelayMs(10);
		temp++ ;
	}
}
void RS485SentData(unsigned char dat)
{
	
		SBUF = dat;
		DelayMs(10);			// Dummy Delay
}
void RS485SentAddressData(unsigned char address,unsigned char dat)
{
	
		SBUF = address;
		DelayMs(10);				// Dummy Delay
		SBUF = dat;
		DelayMs(10);         // Dummy Delay
}
// This function will send any integer value on Hyper Terminal
void main()
{
	 SW = 1;
         int i=0;
     	 SELECT =TRANSMIT      ;
  	 InitSerialInterruptRS485()         ;
         while(1)
         {
                       if(SW==0)
                       {
                                    i++;
                                           RS485SentData(i);
                      }


        }
  	 while(1)                      ;
}


My Code at receiver ends. If any thing receive it will put on 7-Segment

// Code Slave
#include<reg51.h>



sfr  SEG7_2 = 0x80  ;    // PORT 0
sbit SELECT = P3^2 ;
unsigned char SEGMENT[ ] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};


#define TRANSMIT  1
#define RECEVICE  0

void RECEIVE_ISR()	   ;
void InitSerialInterrupt()     ;

char i,k,RECEIVE_ARRAY[10];

void DelayMs(unsigned int period)
{
		int i,j;
		for(i=0;i<period;i++)
				for(j=0;j<250;j++);	
} 
unsigned char Display(unsigned char no)
{
		unsigned char Pattern;
		unsigned char SEGMENT[ ] = {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
		Pattern = SEGMENT[no];  // Pattern to return
		return (Pattern);
}
// This for initializing serial terminal
void InitSerialInterruptRS485() 
{
  TMOD  = 0x20; 	 	  // Timer 0 Mode One
	TH1   = 0xFD;				// Baud Rate 9600
	SCON  = 0x50;	  	// Receive Transmit Enable
	TR1 = 1;		  		// Timer Run
	EA  = 1;	          	// Enable Global Interrupt
	ES  = 1;			  			// Enable Serial Interrupt
	RI  = 0;				      // Clear RI Interrupt
	TI  = 0;             // Clear TT Interrupt 
}
// For interrupt handler
void Seiintr() interrupt 4		
{

	if(TI==1)
	{
		TI=0;
	}				 
	else		
	{
			k = SBUF;
			SEG7_2 = Display(k) ;
			DelayMs(1);				// Dummy Delay
			RI = 0;
	}
}
void main()
{
	  int i=0;
		for(i=0;i<9;i++)
	  {
			SEG7_2 = Display(i) ;
			DelayMs(500);				// Test 7-Segment
		}
		SELECT = RECEVICE     ;
  	InitSerialInterruptRS485()         ;
  	while(1)                      ;
}




Can any body correct it ..
Will Correct Version successfully work on long distance communication ?


--
karan



[ Edited Sat Jun 11 2016, 10:59 AM ]
Sat Jun 11 2016, 10:52 AM
#2
Circuit Diagram
Attachment
Sat Jun 11 2016, 11:34 PM
#3
One thought...
You send 'i', as a value from 0 to 255, but your receive handler
can only handle 0-9.
At 10mS per byte you will not be able to see the result.
I would use a tx delay of 1000 mS.



'i' is declared as an integer, but passed to RS485SentData() as an unsigned char


>Will Correct Version successfully work on long distance communication ?

It should do, but make sure the ground line in the cable (pin 5) is connected
at both ends.





[ Edited Sun Jun 12 2016, 10:47 PM ]
Wed Jun 15 2016, 08:54 AM
#4
Thanks It Works ...

One Master and One Slave .. Can you guide how to write code for One Master and Four Slave ICs.

--
Karan

Fri Jun 17 2016, 12:07 PM
#5
I know i have to use below code at Transmitter End with different addresses .
void RS485SentAddressData(unsigned char address,unsigned char dat)
{
	
		SBUF = address;
		DelayMs(10);				// Dummy Delay
		SBUF = dat;
		DelayMs(10);         // Dummy Delay
}

But Can't modify code at Receiver End for Different addresses.
void Seiintr() interrupt 4		
{
 
	if(TI==1)
	{
		TI=0;
	}				 
	else		
	{
			k = SBUF;
			SEG7_2 = Display(k) ;
			DelayMs(1);				// Dummy Delay
			RI = 0;
	}
}


Thanks in Advance


[ Edited Fri Jun 17 2016, 12:07 PM ]
Fri Jun 17 2016, 11:00 PM
#6
>But Can't modify code at Receiver End for Different addresses.

Just test the first byte, the address, and ignore it if not the right one
The final code should have some sort of timer so the code does
not wait too long for the second byte.

I have not tested this , but it should work.
#define MYADDRESS  1
//#define MYADDRESS  2
//#define MYADDRESS  3
//#define MYADDRESS  4
uchar  addressByte=0;


void Seiintr() interrupt 4		
{
 
	if(TI==1)
	{
		TI=0;
	}				 
	else		
	{
        if (addressByte==0)//if first byte of the pair save the address and return
			 {
			 addressByte=SBUF;  //read the byte ,now addressByte is non zero
			 }
			 else
			 {   //addressByte is nonzero, this must be the data byte
				 k = SBUF;  //read the byte 
				 
				 if (addressByte==MYADDRESS)  //if intended for us use the data.. if not, ignore it
				{
				SEG7_2 = Display(k) ;	 
			    }
			//reset for next time
			addressByte=0;
            } //end else adress byte
       RI = 0;			 //clear rx interrupt flag
     }  //end service rx byte

}
Tue Jun 21 2016, 04:34 AM
#7
Hello,

Thanks , It Works . Master-Slave address Match Perfectly .

Problem is:
But sometimes data send and sometimes Not .I don't know why .


Is there any way I can verify data such as checksum or Transmitter Get sure the data can transmitted .

--
Karam


[ Edited Tue Jun 21 2016, 04:35 AM ]
Wed Jun 22 2016, 07:54 PM
#8
I can't see why it should work sometimes and not others.
How much data are you sending?
Can you post your latest master and slave code.

How far apart are the master and slave ?

Get Social

Information

Powered by e107 Forum System

Conversation

No messages yet.

Downloads

Comments

Mirza123
Thu Jun 25 2020, 03:46 PM
eunicelove124
Mon Jun 22 2020, 03:03 PM
cerouno
Tue Jun 16 2020, 05:10 PM
Marce
Sat Jun 13 2020, 09:43 PM
Davidthils
Thu May 21 2020, 12:44 PM
Jakeror
Thu May 21 2020, 01:28 AM
motorCar
Wed May 20 2020, 07:05 PM
Vordrync
Wed May 20 2020, 11:52 AM

Online

Guests: 159, Members: 0 ...

most ever online: 182184
(Members: , Guests: 182184) on 06 Aug 2010: 05:37 AM

Members: 38215
Newest member: Mirza123