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 use UART robustly?

Dear Friends,

I use UART of MSP430 to communicate with a PC via a UART-to-RS232 module. It functions well, but I need to change delay time between transmitting every byte. The source code was as follows,

int Uart0Tx(char* pcTx, int nLn)
{

   int i;

    for(i=0;i<nLn;i++)
    {
        while(!(UC0IFG & UCA0TXIFG)){}; // till UART Transmit buffer is empty
        UCA0TXBUF = pcTx[i]; // send the character
        Sleep(10);
    }  

    return i;
}

void Sleep(uint32 n_ms)
{
     while (n_ms--)
    {
          __delay_cycles(DELAY_1ms); 
    }
}

When I use UART with baudrate 9600, I set Sleep(10); while I use UART with baudrate 115200, I must set Sleep(100).

If I don't change the Sleep(n), the received side always miss some bytes.  

Did I make anything wrong with UART? Is there any more robust skill to handle UART? 

Thank you very much.

Sunglin.

  • Sunglin Chen said:
    I need to change delay time between transmitting every byte.

    By itself, the UART protocol is capable of supporting a constant stream of data bits. No delay required.

    TXIFG synchronizes when a byte has been sent. Or rather when anotehr byte can be written to TXBUF. The USCI uses double-buffering. So you can write a byte to TXBUf whiel the preious one is being sent, adn the two will go out seamlessly.

    If you need to add 10 ms of delay after each byte, then the receiver apparently cannot handle the incoming data at that speed. At 9600Bd, transmitting one byte takes ~1ms. So the receiver is by a factor of 10 too slow if you need a 10ms delay.

    Anyway, at 115200 you don't need a higher delay. It makes almost no difference whether you send with 9600Bd and 10ms delay (one byte every 11ms) or with 115200Bd and 10ms delay (one byte every 10.1ms). You could as well send with 300Bd and no delay at all.

    However...

    Sunglin Chen said:
    while(!(UC0IFG & UCA0TXIFG)){};

    I assume you're using an MSP430F2xx device. I'm a bit surprised about UC0IFG. IIRC, the IFG register for UCA0/B0 is IFG2. Only for UCA1/B1 it is UC1IFG. But since you don't get a compiler error, maybe someone has decided to generate the non-official UC0IFG as an alias for IFG2. (which I consider a very bad idea, as IFG2 also contains other IFG flags from totally unrelated modules)

**Attention** This is a public forum