We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I am working on a project having three micro controllers.... Out of these three one is master and others are slave.... according to pin conditions of slave,it send some value which is recieve by the master and showed at lcd.... When I use one of the both slave then it is working properly but when I use both the slave it is not working... My programming for this..
void uart_init() { TMOD = 0x20; SCON = 0x50; TL1 = 0xFD; TH1 = 0xFD; TR1 = 1; }
void uart_send(bit_8 value) { SBUF = value; while(!TI); TI = 0; }
bit_8 uart_receive() { while(!RI); RI = 0; return(SBUF); }
I am using same program in both slave becoz both have same circuit...but the value send by the slave are differ...
Yeah I know.... But present time I am working on pcb having no RS232 IC... The Tx of both slaves are directly connected to the Rx of the master...
You can't connect two UART TX signals to one UART RX pin.
Or actually you can - but then the two slaves must reconfigure the processor pin to tristated GPIO pin as soon as the transfer is done so the pin doesn't fight with the other slave TX pin.
And you would then need to either send a message saying "slave 1: talk now" and "slave 2: talk no" or make use of a digital line 0 => slave1 owns the UART, 1 => slave2 owns the UART.
@Per Westermark.... processor pin to tristated GPIO pin ... can u more elaborate this line ...I didn't get this line.... I know this is happening because the both slave r sending data together and that made the line congested.....how can I overcome this problem....
It doesn't matter if both slaves are sending data at the same or not.
If one slave is sending data and the other slave is idle, the two slaves will still fight about with their connected TX pins. What do you think happens when one slave tries to hold the pin high and one wants to hold it low? Which one should win?
That is why the slave that doesn't send has to change the TX pin from UART mode to GPIO mode and make it into an input pin with weak or no pull-up/pull-down. Just to make sure that the idle slave allows the pin to move to any which state the active slave wants that TX pin driven.
Haven't you studied basic digital logic? I.e that outputs can be connected to one or more inputs. But outputs can't be connected to other outputs unless the output pins have some form of enable signal to activate/deactivate the drive. The one exception is for bus designs using dominant/recessive states - like having multiple open-collector outputs connected.
The UART TX signal is not open-collector. And it does not have any enable/disable signal. So it will not tristate between transmissions. This means you has to tell the processor to no longer use it as UART TX to be able to tristate the pin when you don't need to send. And you need to figure out how the slave will know when it's allowed to change the pin back to UART TX mode and make a transmission.
IF ALL uCs ARE ON THE SAME BOARD: if both slaves have TX as quasi or OD and you use a pullup resistor, it will work with a proper protocol
Erik
The tricky thing with a number of 8051 chips is that for GPIO they may behave like a classic 8051 but switch the pin for UART TX to a full totem output when the UART is used.
I know some that do; however, it can be changed by manually handling the configuration instead of BLINDLY relying on some configuration software.
I changed my programming according to u.... I enable the Tx pins of both slave only at the time of sending and after just sending the value,disable it... But it is still not working.....Only one slave is working at a time... my programming as.. /******************For slave one*************************/
void short_test() { if(short1==0 || short2==0 || short3==0 || short4==0) { while(short1==0) {tx=1;uart_send(12);} while(short2==0) {tx=1;uart_send(22);} while(short3==0) {tx=1;uart_send(32);} while(short4==0) {tx=1;uart_send(42);} } tx=0; } /****************For slave two**********************/
void short_test() { if(short5==0 || short6==0 || short7==0 || short8==0) {while(short5==0) {tx1=1;uart_send(52);} while(short6==0) {tx1=1;uart_send(62);} while(short7==0) {tx1=1;uart_send(72);} while(short8==0) {tx1=1;uart_send(82);} } tx1=0; } /***********Master************************/
if(uart_receive()==12 || uart_receive()==22 || uart_receive()==32 || uart_receive()==42 || uart_receive()==52 || uart_receive()==62 || uart_receive()==72 || uart_receive()==82 ) {buzzer=1; send_command_lcd(0xc0,"ZONE SHORT\0"); START1: send_command(0xc4); while(uart_receive()==12) { senddata('1');goto START1; } while(uart_receive()==22) { senddata('2');goto START1; } while(uart_receive()==32) { senddata('3');goto START1; } while(uart_receive()==42) { senddata('4');goto START1; } while(uart_receive()==52) { senddata('5');goto START1; } while(uart_receive()==62) { senddata('6');goto START1; } while(uart_receive()==72) { senddata('7');goto START1; } while(uart_receive()==82) { senddata('8');goto START1; } }
. @erik.. Both of the slave are connected directly to the Rx pin of the master... I have studied that I have to give address to both the slave and master.. But I don't have any idea about how to give address and how to to call them.... Here i am working on a circuit i can not do any changes to it... I can only change my program... So any idea about programming...?
I am thinking to give two connection line between master and slave(for each slave) and then enable the Tx only for sending the data.... it will work...?????
Don't you think it's a good idea to spend some time reading up on all information available on Google?
You can use the UART in "normal" mode, and have the master send: "SLAVE1: Talk\n"
or
"SLAVE2: Talk\n"
To inform either of the slaves to enable the TX pin and send any message and then release the TX pin.
You can also read up on the ability to do 9-bit transfers where the UART hardware can use the extra bit to know if the master sends data or an address byte, and can use this to pick up the address and see if the following message is addressed to slave 1 or slave 2 - and then know if it's ok to enable the TX pin and send any answer back.
Never forget the "R" in R&D - you are supposed to spend some time doing research too. Looking for what possible solutions that are available.
. @Per Westermark I changed my program as show above... Here I enable the Tx pin only for transferring the value and immediately disable... Is above program according to u...? If not than edit same program as u want.....And post here
I don't see anything in your code that indicates that the master tells the slaves which of the slaves that may talk.
If both slaves hear the same command and both slaves thinks they should respond, then both slaves will still make use of the TX line at the same time.
But aren't you actually busy right now debugging your code? Aren't you using an oscilloscope and looking at the signal on the TX line? What does it look like? What did you expect it to look like?
Programming isn't about writing some text, compile, run. Then ask in a forum for what to change before compiling and running again and then back to a web forum.
I am just a beginner and actually I have very less idea about these things... I am just studying through net and apply the things which r necessary for my project if I failed I do same thing again and again till I don't come at any conclusion.... And I am still looking for the codes by which the master tells the slaves which of the slaves that may talk....
You really do have to start to learn how to try to step through your program in your head and consider what really happens.
You have an expression like:
if(uart_receive()==12 || uart_receive()==22 || uart_receive()==32 || uart_receive()==42 || uart_receive()==52 || uart_receive()==62 || uart_receive()==72 || uart_receive()==82 )
But doesn't every call to uart_receive() hand until you have received a single character? How do you think this long expression will manage to synchronize with your two slaves?
Notice the huge difference between your code and:
unsigned char c = uart_receive(); if (c == 12 || c == 22 || ... || c == 82) { ... }
or maybe
unsigned char c = uart_receive(); if (c >= 12 && c <= 82 && (c%10) == 2) { ... }
Beginner or not - if you have multiple friends around you and want to know where they think you should go out and eat do you ask them all at the same time? Or do you instead try to ask them one-by-one? Since all slaves are listening to the same transmission, all slaves will hear any message from the master - so how do let each slave know when a message is aimed for slave 1 or for slave 2?
Using multiple devices on the same serial channel is like having multiple threads sharing a memory resource - you need some form of "critical section" that serializes the access to the shared resource, i.e. only allows one at a time to make use of the UART transmit.
Per,
Clearest answer yet. You nailed it.
(Also, I love the use of 'goto'. You just can't beat that kind of code.)
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA