DAN190
1
EXAR UARTS IN RS-485 APPLICATIONS
April 2008
EXAR UARTS IN RS-485 APPLICATIONS
1.0 INTRODUCTION
This application note discusses the benefits of Exar's patented Automatic RS-485 Half-Duplex Direction
Control feature (patent #6,765,626) available in Exar's enhanced UARTs and how this feature simplifies the
software driver implementation for using UARTs in a half-duplex RS-485 environment.
2.0 HARDWARE CONNECTIONS
Figure 1 below shows the typical connection of a UART to a half-duplex RS-485 transceiver. The same output
from the UART will control both the Driver Enable (DE) and Receiver Enable (RE#) inputs to guarantee that the
RS-485 transceiver is only either transmitting or receiving.
3.0 SOFTWARE CHALLENGES
The main challenge for using a UART in a half-duplex RS-485 environment is making sure that the RS-485
transceiver is in the TX mode before transmitting and that the RS-485 transceiver does not return to the RX
mode until all of the data has been transmitted. The industry standard 16550 UARTs generate an interrupt
when the TX FIFO is empty, however, there may still be data in the Transmit Shift Register (TSR). Therefore,
some additional software is required to ensure that the TSR is also empty when using a UART that does not
have Exar’s Auto RS-485 Half-Duplex Direction Control Feature.
F
IGURE 1. TYPICAL CONNECTION BETWEEN UART AND RS-485 TRANSCEIVER
FIGURE 2. UART TRANSMIT INTERRUPT BEHAVIOR
TX
RX
(RS-485 Direction
Control Output)
RS-485
Transceiver
TX+ / RX+
TX
RX
DE
RE#
TX- / RX-
UART
TX output
TX FIFO empty interrupt
generated here
TX FIFO TSR
TX FIFO
EMPTY
DATA
DAN190
2
EXAR UARTS IN RS-485 APPLICATIONS
3.1 Possible Software Solutions
3.1.1 Polling Example
The first way to do this is to poll the LSR register. Let’s assume that the RTS# signal is used to control the
direction of the RS-485 transceiver and RTS# needs to be HIGH for transmit and LOW for receive.
//Initialization
IER = 0x00; //Interrupts are not enabled
MCR bit-1 = 1; //Set RS-485 transceiver in RX mode
...
//Transmit Routine
MCR bit-1 = 0; //Set RS-485 transceiver in TX mode
Write data to TX FIFO (THR);
While (LSR bit-6 == 0); //wait until the TX FIFO + TSR is empty
MCR bit-0 = 1; //TX completed, set RS-485 transceiver back to RX mode
However, this is not very efficient since the CPU/MCU has to wait for this routine to finish.
3.1.2 Interrupts + Polling Example
The other way is to use the TX empty interrupt. However, even when using the TX empty interrupt, the
software still needs to poll the LSR register as described in section 3.0.
//Initialization
IER = 0x02; //TX empty interrupt enabled
MCR bit-1 = 1; //Set RS-485 transceiver in RX mode
...
//Transmit Interrupt Service Routine
if (more data to send)
MCR bit-1 = 0; //set or keep RTS# pin HIGH for TX mode
else {
while (LSR bit-6 == 0); //poll until TX FIFO + TSR is empty
MCR bit-1 = 1; //TX completed, set RS-485 transceiver back to RX mode
}
while (more data to send AND data less than FIFO size)
write data to THR;
This is more efficient than the polling example, but there is still a while loop that keeps the CPU/MCU busy
when it can be doing other tasks.