A UART , otherwise known as aserial port, is a commonly included peripheral on many microprocessorsand MCUs. Asynchronous serial ports provide a simple way for twodevices to communicate without having to share a common clock signal.
With the addition of an appropriate voltage level shifter, a serialportcan also be used to communicate over RS-232and RS-485 networks or toconnect to the communication port of acomputer. Only two signal lines (Rx and Tx) are required to implement aserial interface.
Why a software UART? Three reasons.
Now, with all the available MCUs that have serial ports provided inhardware, why implement a UART in software using MCU port pins?
First, although many microcontrollers (MCUs) have UARTs implemented inhardware, many still don't. When selecting an MCU for a system design,it can be difficult to find a perfect fit. One MCU might run over thedesired voltage ranges, but have insufficient memory.
Another might have more than adequate memory size, but not enoughport pins to meet the design requirements. The ability to “fill in thegaps” in an MCU's feature set by implementing required peripherals insoftware increases the number of MCUs that can be considered for agiven design, thus increasing flexibility.
Second, an MCU might have a perfectly good hardware UART, but for whateverreason, it might be inadequate for the design at hand. Perhaps the MCUneeds to communicate with a peripheral that runs on a slightly modifiedversion of the serial protocol or maybe the number of bits, paritychecking features or I/O buffers provided by the hardware UART do notfit the application requirements exactly. By building software UART,there is greater flexibility in definingUART capabilities and serial protocol details.
Third, anMCU might havehardware UARTs that fit an application perfectly, but simply not haveenough of them. Perhaps the MCU has two UARTs and the applicationrequires three. Instead of adding a new chip to the design, anotherUART can be added into the software.
How much bandwidth will be lost?
The next question is how much bandwidth will be taken away from themain application by implementing a UART in software.
After all, one of the primary reasons for implementing UARThardware is to free the MCU from having to occupy its time with thelow-level details of the serial protocol. Instead, the tediousbit-sampling, timeslot counting, and I/O bit shifting are all handledin hardware, and the UART alerts the main MCU that it has eitherreceived a character or has finished transmitting one.
The MCU can then quickly load or unload data from the UART bufferas needed and then return to its core tasks.
If implementing software UART means that the application will spendlarge amounts of time spinning in place while it watches port pins forserial activity, it's probably not worth doing.
Fortunately, this is not the case. Consider the standard 10 bitasynchronous serial protocol (1 start bit, 1 stop bit and 8 data bits)when transmitting and receiving a character.
Once a transmit or receive operation has started, the serial UART(in either software or hardware form) does not need to monitor the I/Olines continuously. (Figure 1, below).
|Figure1. Once a transmit or receive operation has started, the serialUART does not need to monitor the I/O lines continuously|
When transmitting a character, the UART only needs to drive thestate of the transmit line once every bit period, setting the level foreach bit in turn, from the start bit through eight data bits to thestop bit.
When receiving a character, the UART begins its activity on thefirst falling edge. After this point, the UART only needs to sample thereceive line state once in the middle of each bit timeslot.
Implmenting the UART state machines
A pair of state machines – one dedicated to transmitting characters andone to receiving them – can represent the desired behavior of softwareUART. For a full-duplex UART, both of these state machines run inparallel, which requires two independent timer interrupts.
Both state machines have active and inactive modes. The transmitstate machine transitions out of its idle state when it is given acharacter to transmit, and goes back to idle state following thetransmission of the stop bit.
The receive state machine transitions out of idle state when itdetects a falling edge on the receive line. Once it sees this initiallow state, it begins counting off its bit timeslots and samples theline for each bit as needed, including the stop bit.
To avoid occupying any more of the main application's time thannecessary, the UART state machines should be activated by periodictimer-based interrupts.
The initial falling-edge detection for the receive line is handledseparately, with an external edge triggered interrupt. If a statemachine's timer is set to fire off an interrupt once per bit period,the state machines can perform any needed operations (and advance tothe next state if needed) each time the interrupt is triggered.
The code needed to implement the state machines should be optimizedas much as possible, since it will be continuously running in thebackground whenever the software UART is active.
Aaron Minor is a senior engineerat MaximIntegrated Products Inc.