This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RS485 & UART TX & RX directional bit problem



Hi all,

I have 2 MCUs communicating in RS485 style. I am able to transmit a character "A" from MCU1 (master) to MCU2 (slave)by a push-button. (Initial GPIO pin of RS485 for MCU1 is high & GPIO pin of RS485 MCU2 is low).

MCU2 received the character "A" correctly & light up LED2. Thus, MCU2 (slave) acknowledge this by sending back 2 character "OK" to MCU1 & light up LED1 of MCU1. (The GPIO of both MCUs are toggled in order to perform the above operations).

However, if I add the command highlighted below to switch the GPIO pin of RS485 of MCU2 (slave) back to low. The above operation of transmitting "OK" fails. If i remove the highlighted command, MCU1 receive it correctly (monitor by HyperTerminal)

Why is that so? I need to set it low to continue to listen. How should I correctly set my P5OUT BIT7 back to low to listen?

 

The interrupt code of both Tx & Rx (for MCU2) is as follows:

#pragma vector=USART0TX_VECTOR

_interrupt void usart0_tx (void)

{

TXBUF0 = string[i++];    //To transmit "OK" to MCU1
if(k == sizeof string -1)

IE1 &= ~UTXIE0;       //disable Tx interrupt of MCU2

 

P5OUT &= ~BIT7;   //Set RS485 pin of MCU2 back to low

}

 

#pragma vector=USART0RX_VECTOR

_interrupt void usart0_rx (void)

{

if(RXBUF0 == 'A')  //check for transmission from MCU1 for incoming "A"

{

i=0;

P5OUT |=BIT7; set the RS485 pin to transmit of MCU2 so that it prepares to acknowledge

P4OUT |=BIT1;  on led 2 of MCU2

IE1 |=UTXIE0;    //Enable tx interrupt

TXBUF0 = string[i++];

}

 

 

 

 

 

 

  • I am not sure you are checking remaining chars in string buffer correctly, in tx routine. Sizeof() does not measure lenght of char string. Also - you "Set RS485 pin of MCU2 back to low" after every TX buffer write, not after last char is sent out of usart.

  • Hi llmars,

    Thanks for the feedback. Say, I removed the P5OUT bit low command. I see the string "OK" at the hyper terminal.

    Even when I added in the command, say I set it to low after every Tx buffer write, why don't I just see the first character which is "O"?

    Any idea how to check for last char to be sent out? Thanks. 

  • John Chan1 said:

    I set it to low after every Tx buffer write, why don't I just see the first character which is "O"?

    Because buffer write does not mean that char is sent.

     

    John Chan1 said:
    Any idea how to check for last char to be sent out? Thanks. 

    TX interrupt fired but you don't have any chars left to send.

  • John Chan1 said:
    Even when I added in the command, say I set it to low after every Tx buffer write, why don't I just see the first character which is "O"?

    Due to the buffering. When you write to TXBUF, it ill start sending. However, the processor continues in the meantime. And sending serially is slow. The processor can do lots of things while the bits are shifted out. The only thing it must not do is to disable the RS485 transmitter :)
    Even worse, when you writ eto TXBUF the first time, its content will be moved to the output shift register immediately, and TXBUF is empty again, causing another interrupt.
    So your ISR has written the 2nd byte to TXBUF and disabled the transmitter, likely before even the start bit of the fist byte has been sent.
    With your current code, you will see everythign but the last two bytes. Unfortunately your OK is only 2 bytes  long :)

    John Chan1 said:
    Any idea how to check for last char to be sent out?

    Once both, TXBUF (indicated by TXIFG) and the output shift register are empty, the TXEPT bit is set. You must wait for it before you disable the transmitter. Or even a bit (literally the length of a bit) more, to avoid any reflections on the bus disturbing the reception of the last sent byte.

**Attention** This is a public forum