Continue to Site

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.

[moved] Communication Problem RS-485 MASTER and SLAVE

Status
Not open for further replies.

aacs

Newbie level 2
Newbie level 2
Joined
Sep 3, 2015
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
17

Hi,

I am working on a project of interfacing PIC uP (MASTER) to Multiple PIC uP (SLAVES) through the use of half-duplex RS-485 chips.

I am using daisy chain topology for my network.

Hardware configurations:
-----------------------------
all of the RS-485 chips are connected as follow to the PIC uP:

RS-485 pin PIC16F876
------------- -------------
RO RC7(RX)
RE' RC5
DE RC5
DI RC6(TX)

120ohm termination resistor on the Master side




Software Configurations:
-----------------------------
Compiler: HT-PIC C

I am using rs232 subroutines, except that before I call my subroutine, I switch on and off RC5 accordingly to what ever operation I am currently trying to implement.

that is if I am trying to transmit, I set RC5 to 1 and then I call putchar() subroutine. then once I have finished transmitting I set RC5 to 0 before I call getchar() subroutine.


The following is the software code:
====================================


1: /*==========================================================================*/
2: /* Send 8-bit char using USART and Interrupt handler */
3: /*--------------------------------------------------------------------------*/
4: void putchar (unsigned char data_out)
5: {
6: serial_time = 10; // format timeout value for serial comm
7:
8: while (!TXIF && serial_time) // Wait until transmit reg empty using interrupt flag: TXIF
9: {
10: line_error();
11: }
12:
13: TXREG = data_out; // Write to Transmiter register
14:
15: return; // Resume PIC normal operation
16: }
17:
18: /*==========================================================================*/
19: /* receive 8-bit char using USART and Interrupt handler */
20: /*--------------------------------------------------------------------------*/
21: bit getchar(unsigned char *data_in)
22: {
23: serial_time = 10; // format timeout value for serial comm
24:
25: while (!RCIF && serial_time) // Wait until character is received using Interrupt flag: RCIF
26: { // Loops until user send info.
27:
28: line_error();
29: }
30:
31: if (!serial_time)
32: {
33: return (FALSE);
34: }
35:
36: *data_in = RCREG; // assign incoming data to DATA_IN.
37:
38: return(TRUE); // Resume PIC normal operation
39: }
40:
41: //==============------------- MAIN PROGRAM ---------------==================
42:
43: /*========================================================================*/
44: /* The Main Program */
45: /*------------------------------------------------------------------------*/
46: main(void)
47: {
48: unsigned char bydata; // counter variable
49: unsigned char sData[3]; // outgoing buffer from MASTER to SLAVES
50: unsigned char sData2[3]; // incoming buffer from SLAVES to MASTER
51:
52:
53: InitProc(); // Initialize uP and registery
54: serial_init(31,1); // Init. serial port
55:
56: sData[0] = 0x01; // SLAVE device address
57: sData[1] = 0x0C; // Poll command
58: crcValue = 0xFF; // initialize crcValue;
59:
60: sData2[0] = 0x00; // Clear Incoming buffer.
61: sData2[1] = 0x00;
62: sData2[2] = 0x00;
63:
64:
65: while(1)
66: {
67: bydata = 0x00; // reset counter
68:
69: RS_485_crc_CALC(sData, 3); // Calculate crcValue
70:
71: sData[2] = (255 - crcValue); // append crc value to outgoing buffer
72:
73: crcValue = 0xFF; // Reset crcValue
74:
75: // Prepare the MAster to transmit data to slaves
76: //-----------------------------------------------
77: RC5 = 1; // enable RS-485 driver (transmitter)
78: TXEN = 1; // enable transmitter
79: CREN = 0; // disable receiver
80:
81: for (bydata = 0; bydata < 3 ; bydata++)
82: {
83: putchar(sData[bydata]); // Send out the data to slaves
84: }
85:
86: // Prepare the master to receive data from slave
87: //------------------------------------------------
88: TXEN = 0; // Disable Transmitter
89: CREN = 1; // Enable Receiver
90: RC5 = 0; // Enable RS-485 Receiver
91:
92: for (bydata = 0; bydata < 3; bydata++)
93: {
94: getchar(&sData2[bydata]); // receive incoming data from slaves
95: }
96:
97: // Heart Beat Indicator :: inidicate that the pic has reached the end of code cycle.
98: if (!LEDTime) // Check Countdown
99: {
100: RA4 = (RA4 == FALSE);
101: LEDTime = TIMER1_LED_DELAY; // Restart
102: }
103:
104: CLRWDT();
105:
106: }
107:
108: }
109:

The above code does not work.


But if you insert the following lines:

for(i=0; i<95; i++); between lines :: 83 and 84.
for(i=0; i<5000; i++); between lines :: 103 and 104.


The slave successfully receives the poll command, but still the MASTER can not receive the response back from the slave.


IS THIS A SOFTWARE ISSUE?
IS THIS A TIMING ISSUE?

Hi does your code work out? can you help me please i could not communicate between master and slave using rs485
 
Last edited by a moderator:

Hi,

To hardware:
* RS485 is a two wire bus, differential signalling, plus ground signal.
* It needs differential pair wiring with a wave impedance of about 120 Ohms.
* All devices are connected in a string ==> No star wiring.
* The master does not need tof be connected at one end, it may be placed anywhere in the bus,
* Both bus ends need to be terminated with 120 Ohms each (independent of master connection)
* The bus should be biased to get a valid high signal when bus is idle = all drivers are off.
* All receiver may be enabled all the time. If disabling, then TTL Rx data output needs a pullup.
* Only one (or none) driver should be enabled in a time

Software:
* when interrupt flags are used, but no ISR, then the flags need to be cleared manually (I don't see here)
* The bus must be released after transmission (Disable driver). This can be done after each byte or after each frame. But take care not to disable the transmitter too early. Not after storing the byte into the UART transmit buffer, but after the STOP bit is transfered to the bus.
* there is no need to disable/enable UART receive/transmit periferal. Both may be ON all the time, but you will receive your own sent out data (echo).

Klaus
 

Hi,

To hardware:
* RS485 is a two wire bus, differential signalling, plus ground signal.
* It needs differential pair wiring with a wave impedance of about 120 Ohms.
* All devices are connected in a string ==> No star wiring.
* The master does not need tof be connected at one end, it may be placed anywhere in the bus,
* Both bus ends need to be terminated with 120 Ohms each (independent of master connection)
* The bus should be biased to get a valid high signal when bus is idle = all drivers are off.
* All receiver may be enabled all the time. If disabling, then TTL Rx data output needs a pullup.
* Only one (or none) driver should be enabled in a time

Software:
* when interrupt flags are used, but no ISR, then the flags need to be cleared manually (I don't see here)
* The bus must be released after transmission (Disable driver). This can be done after each byte or after each frame. But take care not to disable the transmitter too early. Not after storing the byte into the UART transmit buffer, but after the STOP bit is transfered to the bus.
* there is no need to disable/enable UART receive/transmit periferal. Both may be ON all the time, but you will receive your own sent out data (echo).

Klaus

Thanks Klaus,
I understand what you are saying but I do not know how to start. If you have any sample with this can you please post it.
 

Hi,

I don't have code.

You now need to think about a protocol.
Either you use a standard one like modbus (check if this is what you needs)
Or you need to develop your own protocol.

Before starting to program you need to decide about:
* baud rate,
* min bus idle timing
* arbitration
* addressing
* frame sync
* frame size (variable/fixed)
* crc, and how to handle bad packets (discard/resend)
* slave respond time
* timeouts
* how to detect and how to handle, if one device freezes the bus
...
Please do the paperwork first, then start to program.

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top