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.

RS485 communication is not successful

Justinli

Member level 3
Joined
Apr 29, 2021
Messages
67
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
353
Use PIC18F452 to connect MAX485 chip for 485 communication, then connect to PC through the interface which is 485 transfer to USB, using the serial assistant to send and receive data, but the communication is not successful, no data is received, and no data can be sent.

1531190117_667474.jpg


The code is as follows:

Code:
#include
#include

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

unsigned char FIFO;
char flag=0;

void delayms(uint z)
{
uint a,b;
for(a=z;a>0;a--)
for(b=120;b>0;b--);
}

void init_uart()
{
TRISC=0x80;
TXSTA=0X24; //enable the serial port to send 8-bit data
RCSTA=0X90; //enable the serial port to work and receive continuously
SPBRG=25; //Set baud rate to 9600BPS 4000000/9600/16-1=25
RCIE=1; //receive interrupt
GIE=1; //global interrupt
PEIE=1; //external interrupt

}

void IO_INIT(void)
{
ADCON1=0xFF; //Disable AD conversion function (second function)
TRISE = 0;
TRISC = 0X00;
TRISD = 0;
PORTD = 0;
TRISA = 0;
TRISB = 0X00;
PORTB = 0;
//PORTE = 0XFF;
RE0 = 0;
RE1=0;
RE2=0;
RBPU=0;
}

void Send_Date(unsigned char date)
{
TXREG=date;
delayms(2);
while(TXIF==0);
TXIF=0;

}

// --------------------------------------------------------------------------------------------------
// Function name: serial() serial port receive interrupt handling function
// Function: Receive data into the data buffer
// --------------------------------------------------------------------------------------------------

void interrupt usart()
{
if(RCIF) // determine if it is a serial receive interrupt
{
RCIF=0;
FIFO=RCREG; // Receive data and store
flag=1;
}
}
void main()
{
uint x;
IO_INIT();// IO initialization
init_uart();
while(1)
{
/// /* 2018.7.2 Sending program
if(flag)// data received send
{
flag=0;
Send_Date(FIFO);
delayms(5);
RCIF=0;
}

delayms(100);

if(x++>15)//Send data once in a while
{
x=0;

Send_Date('T');
Send_Date('e');
Send_Date('s');
Send_Date('t');
Send_Date('o');
Send_Date('k');
Send_Date(0x0d);
Send_Date(0x0a);

delayms(5);
RCIF=0;

}
}

}
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
15,126
Helped
4,935
Reputation
9,890
Reaction score
4,741
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
128,433
Data goes to 'DI', The direction control goes to the base of the transistor.
You can't reverse the data flow direction using the logic level of the data alone, all it does is either transmit a bit or turn the transmitter off. You need an extra control signal, it could connect directly to the RE and DE pins and then the transistor and 12K resistor removed.

Also not sure why you keep clearing RCIF. You only have to clear it in the ISR, not in the main loop.

Brian.
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
20,352
Helped
4,441
Reputation
8,891
Reaction score
4,468
Trophy points
1,393
Activity points
134,556
Hi,

DI:
there are "control free" solutions. But they use a delay to switch OFF driver after sending data.
* The delay time depends on baud rate and "bus idle before send timing"
* you need "fail safe receivers" or you need to bias the bus lines to show "idle state" when not driven.
* all bus partners need to comply with this timing.

RE could always be active. Otherwise you need a pull up resistor on RO to prevent from floating.

Klaus
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,749
Helped
14,307
Reputation
28,877
Reaction score
13,035
Trophy points
1,393
Location
Bochum, Germany
Activity points
281,548
This "poor mans" auto direction control might work under circumstances, at least for short cables. A better design would at least delay TX disable by a few µs to drive both edges actively to the RS-485 bus instead of relying on the bias resistors.

It's relative easy to drive RE/nDE by a third PIC GPIO pin, this would be the preferred solution. Auto direction control should be only used if you don't have an option to generate the signal in your hardware.

I would use an oscilloscope in the first place to check what's actually going wrong.
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
20,352
Helped
4,441
Reputation
8,891
Reaction score
4,468
Trophy points
1,393
Activity points
134,556
HI,

I see no benefit in using RE at all. It´s just more effort in HW and SW .... unless you want to multiplex several receivers to one UART.

Klaus
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
20,352
Helped
4,441
Reputation
8,891
Reaction score
4,468
Trophy points
1,393
Activity points
134,556
Hi,

yes, I did echo prevention. But I always did it by disabling the UART receiver within the microcontroller.
It needs no I/O, no wiring, no pull up.

I see two benefits in using RE:
* multiplexing
* power saving

Klaus
 

Justinli

Member level 3
Joined
Apr 29, 2021
Messages
67
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
353
It's sometimes used to prevent echo of own TX data in hardware. I doubt however that RE is the problem here.
I found a solution by shorting pin 2/3 (where RE/DE is) with a pull-down resistor and assigning an IO to control the 485 modes of operation.
 

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top