Long Distance(100 Meter) Multi-point Communication with RS-485 SN75176
Discussion in "8051 Discussion Forum" started by Karan123 Jun 11, 2016.
Sat Jun 11 2016, 04:12 pm
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
My Code at receiver ends. If any thing receive it will put on 7-Segment
// Code Slave
Can any body correct it ..
Will Correct Version successfully work on long distance communication ?
--
karan
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, 04:29 pm ]
Sun Jun 12 2016, 05:04 am
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.
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 Mon Jun 13 2016, 04:17 am ]
Wed Jun 15 2016, 02:24 pm
Thanks It Works ...
One Master and One Slave .. Can you guide how to write code for One Master and Four Slave ICs.
--
Karan
One Master and One Slave .. Can you guide how to write code for One Master and Four Slave ICs.
--
Karan
Fri Jun 17 2016, 05:37 pm
I know i have to use below code at Transmitter End with different addresses .
But Can't modify code at Receiver End for Different addresses.
Thanks in Advance
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, 05:37 pm ]
Sat Jun 18 2016, 04:30 am
>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.
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, 10:04 am
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
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, 10:05 am ]
Thu Jun 23 2016, 01:24 am
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 ?
How much data are you sending?
Can you post your latest master and slave code.
How far apart are the master and slave ?
Powered by e107 Forum System