AVR274: Single-wire Software UART

on
UART communications are usually implemented using separate data wires for
reception and transmission. A single-wire UART is using only one wire for
communication, and is therefore ideal in low cost solutions where no high-speed
full duplex communication is needed. This application note describes a software
implementation of a single wire UART. The protocol supports half duplex
communication between two devices. The only requirement is an I/O port
supporting external interrupt and a timer compare interrupt.




2
AVR274
2 Theory of Operation
2.1 UART frame
The UART protocol is an asynchronous serial communication standard. Data is
transferred sequentially, one bit at a time. This implementation uses a frame
consisting of 8 data bits, one start bit and two stop bits as shown in Figure 2-1. Other
implementations may use different frame formats consisting of 5 to 9 data bits, 1
parity bit for error control and 1 stop bit. The line is high when no transmission is
ongoing.

Figure 2-1. UART frame format
Frame
Start
Bit
D0
D5
D3
D2
D4
Bit Period
D6
D7
D1
Receiver
sampling
Stop
Bits


Figure 2-2. Serial frame for ASCII a (0x61)
Start
Bit
1
1
0
1
0
0
0
Stop
Bits
0

2.2 Transmission
Transmission is initialized by sending the start bit (pulling the line low) for one bit
period. The receiver detects the falling edge and is then able to synchronize to the
transmitter. The least significant bit of the data bits is sent first.
Open collector outputs are used to drive the line, but if both devices are transmitting
at the same time, the transmitter sending a low bit will pull the line low even if the
other transmitter is sending a high bit. To handle this situation the UART never starts
transmitting while receiving. The transmitter is also sampling the line before
transmitting a new bit to make sure the line has not changed since the last bit was
transmitted. An error flag is set if a low bit is received when a high bit was last
transmitted.
2.3 Reception
Reception is started when the start bit is detected. The data bits are then sampled in
the middle of every period. The first data bit is then sampled one and a half bit period
after the start bit is detected. This implementation is not using the three samples
majority vote found in most hardware UARTs to minimize clock cycles used by the
driver.
8065A-AVR-03/07
AVR274


3
8065A-AVR-03/07
2.4 Baud Rate
In UART communication speed is defined by the baud rate. The baud rate is in this
case equal to the number of bits transmitted per second including the start and stop
bits. The receiver and transmitter have to be set up using the same baud rate, or else
they will not be able to synchronize. Common baud rates are 4800, 9600, 19200,
28800 and 38400, but other rates may also be used.
2.5 Error Conditions
There are several error conditions that can occur. If the baud rate differs too much on
the two devices, they can get unsynchronized. Since the baud rate is dependent on a
clock frequency, this problem can occur if the clock differs from the intended value. If
using an internal RC oscillator, it is recommended to calibrate it before using the
UART. Please refer to relevant application notes on how to calibrate the internal RC
oscillator.
The received data byte is stored in a single byte buffer. If the data is not handled
before the next byte is received, the buffer is overflowed and old data overwritten. An
overflow flag is set if this occur. To help this situation UART speed can be reduced,
buffer increased, or the receive routine may be called more frequently if possible.
If a noise pulse forces the line low, the AVR will detect the falling edge and start
receiving. If the start bit is received as a high bit the AVR will stop reception and not
save any data, but if the noise pulse lasts more than a couple of cycles a corrupted
byte will be saved.
Noise may also corrupt a frame under transmission. A bit is sampled only once so the
frame will have an incorrect value if only one sample is corrupted by noise. To detect
these errors a parity bit can be added to the UART frame.
Since an interrupt driven approach is used, application code may execute in parallel
to the UART communication. Note that if other interrupt sources are active this may
affect the UART timing and may cause the UART communication to fail.
It is recommended to use the driver in a master/slave configuration where the slave
only sends data when requested by the master. This will prevent situations where
both devices are transmitting at the same time. If the slave is in an error condition it
may signal the master by pulling the UART line low for a specified time. The masters
error flag will then be set, and the communication may be continued when the slave
stops pulling the line low.
3 Implementation
The code described in this application note is written as drivers for the UART
communication.
3.1 Baud Rate Settings
A timer compare interrupt is used to generate the bit sampling and bit transmission
intervals. The timer is set in Clear Timer on Compare (CTC) mode and to generate an
interrupt when the timer equals the output compare register. The time between each
interrupt is dependent on the system clock, timer prescaler and value in the compare
register as shown in Equation 3-1. Setting the compare value to 10 will generate 11
ticks between each interrupt. Baud rate settings are set in the UART header file
(single_wire_UART.h).
4
AVR274

Equation 3-1. Baud Rate Calculation
rescaler
P
Timer
Setting
Compare
Period
One
Clock
System
Rate
Baud +
=
)
1
(


Equation 3-2. One Period Compare Setting Calculation

1
=
rescaler
P
Timer
Rate
Baud
Clock
System
Setting
Compare
Period
One


Table 3-1 shows timer settings for some common clock speeds and baud rates. The
error values are calculated using Equation 3-3.

Table 3-1. One Period Settings for 1, 2, 4 and 8 MHz Oscillator
1 MHz Oscillator
2 MHz Oscillator
Baud
Rate
(bps)
One Period
Setting
Prescaler
Setting
Error
One Period
Setting
Prescaler
Setting
Error
4800
207
1 -0.16%
51 8 -0.16%
9600
103
1 -0.16%
207 1 -0.16%
19200 NA
103
1
-0.16%

4 MHz Oscillator
8 MHz Oscillator
4800
103
8 -0.16%
207 8 -0.16%
9600
51 8 -0.16%
103 8 -0.16%
19200
207
1 -0.16%
51 8 -0.16%
28800
138
1 0.08%
34 8 0.82%
38400
103
1 -0.16%
207 1 -0.16%

Equation 3-3. Error calculation
%
100
)
1
(
[%]
=
Rate
Baud
Rate
Baud
Error
Match
Closest


Please note that there is a maximum setting for the baud rate. This is because the
timer interrupt has to be finished before a new interrupt is generated. Equation 3-4
gives the maximum baud rate possible. The interrupt must finish before a new
compare interrupt is triggered. The maximum cycles in a compare interrupt are about
100-110 depending on the compiler settings. Using a 1MHz system clock the
maximum baud rate is about 10,000 bit/s. The UART will consume about all CPU
resources when communicating at this baud rate. The application using the UART
must also have time to read the received data before a new frame is received, or else
an overflow error will occur. It is recommended to set the baud rate well below the
maximum setting depending on the application.
8065A-AVR-03/07
AVR274

Equation 3-4. Maximum Baud Rate Setting
Interrupt
Compare
in
Cycles
Maximum
Clock
System
Rate
Baud
<


3.2 Hardware
This implementation is designed using an external pull-up circuit. The I/O pins must
therefore use open-collector outputs. In addition they need to generate an external
interrupt to detect an incoming frame.
A typical value for a pull-up resistor on an AVR microcontroller is 15-40k . When
sending a high bit or receiving the AVR port is tri-stated. A low bit is sent by
configuring the port to output low.
If communicating with a device supporting the RS-232 standard, voltage levels from
about -15 to 15V are needed. A circuit is then needed to convert the signals to these
voltages. An example of a single chip interface circuit is Maxims MAX232. It operates
from a single 5V power supply, and has an onboard DC/DC converter to generate the
RS-232 levels.

3.3 Status register
The single-wire UART has a status register containing the following four flags:

SW_UART_TX_BUFFER_FULL
Set if TX data is ready to be transmitted. This flag must be zero when calling the
SW_UART_transmit function.

SW_UART_RX_BUFFER_FULL
Set if data is available in the receive buffer. This flag must be one when calling the
SW_UART_Receive function.

SW_UART_RX_BUFFER_OVERFLOW
Set if incoming data is lost due to overflow in the receive buffer.

SW_UART_FRAME_ERROR
Set when receiving if a high start bit or a low stop bit is sampled. Also set when
transmitting if a different bit then the last transmitted is sampled.
To decrease code size and increase speed the status register may be put in a GPIO
register if available. (Not available on the ATmega32).
3.4 UART counter
A counter variable is used in the UART driver to control the state and which bit to be
transmitted/received by the UART. The UART is idle when the counter value is 0. The
counter value is even when transmitting and odd when receiving as shown in Figure
3-1.

5
8065A-AVR-03/07
6
AVR274
Figure 3-1. UART Counter Values
Start
Bit
D0
D5
D3
D2
D4
D6
D7
D1
Reception
1
3
5
7
9
11
13
15
17
19
2
4
6
8
10
12
14
16
18
Transmission
Stop
Bits
20
22
21
23