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.

How to stop UART transmitting while receiving?

Currently I am working on a project which requries TX and RX share the same data line.

Thus, I connected UART TX with RX and start with a RX interrupt. However, when I send a message from PC and msp430 goes into RX interrrupt, msp430 transmit the message back immediately. 

For example, with RX and TX connected together, I wrote a code that when msp430 receive a 0x31, it will return a 0x0D. However, the result I got is: I transmit a 0x31, I got 0x31 0x0D back.

Is that possible to stop TX function when TX and RX are connected together?

My code is attached. Many many thanks!

int main(void)
{
      P1SEL = 0X06;                     // P1.1 = RXD, P1.2=TXD
      P1SEL2 = 0X02;                    // P1.1 = RXD, P1.2=TXD
      P1OUT = 0X00;
    a=x=i=0;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  if (CALBC1_1MHZ==0xFF)                    // If calibration constant erased
  {
    while(1);                               // do not load, trap CPU!!
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;


  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

//  Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
      Received[1] = UCA0RXBUF;
       if(UCA0RXBUF == 0X31)
       {
       IE2 |= UCA0TXIE;
       }
          P1SEL = 0X04;                     // P1.1 = RXD, P1.2=TXD
          P1SEL2 = 0X04;                    // P1.1 = RXD, P1.2=TXD
          P1OUT = 0X00;
  a++;
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
      //while (!(IFG2 & UCA0TXIFG));
      UCA0TXBUF = 0x0D;                 // TX next character
      __delay_cycles(5000);
      IE2 &= ~UCA0TXIE;                       // Disable USCI_A0 TX interrupt
      P1SEL = 0X02;                     // P1.1 = RXD, P1.2=TXD
      P1SEL2 = 0X02;                    // P1.1 = RXD, P1.2=TXD
      P1OUT = 0X00;
      b++;
}

  • Hello,

    correct me if I am wrong but in my opinion the UART is always inherently sending and receiving at the same time. This function is relised in hardware in the semiconductor, so it is impossible to change that.

    However it might be possible that I am wrong, and that I am mixing SPI I2C and UART altogether, but at least you have a starting point, and some others in here for sure know :)

    Best wishes,

    Seb

  • yunxi Liu said:
    Is that possible to stop TX function when TX and RX are connected together?

    Yes. You shall search this forum for "rs485" keyword. If can't find answer such way - you are welcome to ask here again.

  • If I understand correctly what you're doing: The MSP430 is not transmitting back the 0x31, the wires are. What your host is seeing on (its) Rx is its own transmission.Your task is not to disable Tx when you're Rx-ing, but rather to disable Rx when you're Tx-ing.

    The code here (fiddling with P1SEL) appears to do this for the MSP430 side. You'll need to make your host side do the same thing.

  • yunxi Liu said:
    For example, with RX and TX connected together, I wrote a code that when msp430 receive a 0x31, it will return a 0x0D. However, the result I got is: I transmit a 0x31, I got 0x31 0x0D back.

    You don't get 0x31 back, you see the 0x31 you are sending, as you are at the same time listening. (loopback)

    When using a 485 transceiver, which also ensures that not both sides send at the same time, damaging their output pins (the transceiver is designed to bear this conflict on its outputs), you have separate control pins for enabling the transmitter and the receiver. The two signals are inverted, so you can connect them and switch between transmit and receive with one port pin.

    Well, RS485 isn't exactly low-power and requires at least three additional resistors (two for defining the idle state if nobody is sending and one for terminating the bus on the other side). However, if you implement some sort of round-robin mechanism, you can have a larger number of peers all listening and talking to each other. With just two signal lines (not even GND)

**Attention** This is a public forum