AVR274: Single-wire Software UART

AVR274: Single-wire Software UART
Features
•
•
•
•
•
Software implemented UART
Half-duplex single-wire communication
Interrupt driven
Supports baud rates up to 9600 @ 1MHz System Clock
Compatible with any AVR® supporting external interrupt and a 8-bit timer compare
interrupt
8-bit
Microcontrollers
Application Note
1 Introduction
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.
Rev. 8065A-AVR-03/07
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
Receiver
sampling
Start
Bit
D0
D1
D2
D3
D4
D5
D6
D7
Stop
Bits
0
1
1
0
Stop
Bits
Bit Period
Frame
Figure 2-2. Serial frame for ASCII ‘a’ (0x61)
Start
Bit
1
0
0
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.
2
AVR274
8065A-AVR-03/07
AVR274
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 master’s
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).
3
8065A-AVR-03/07
Equation 3-1. Baud Rate Calculation
Baud Rate =
System Clock
(One Period Compare Setting + 1) ⋅ Timer Prescaler
Equation 3-2. One Period Compare Setting Calculation
One Period Compare Setting =
System Clock
−1
Baud Rate ⋅ Timer Prescaler
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%
103
1
-0.16%
19200
NA
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
Error [%] = (
Baud Rate Closest Match
Baud Rate
− 1) ⋅ 100 %
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.
4
AVR274
8065A-AVR-03/07
AVR274
Equation 3-4. Maximum Baud Rate Setting
Baud Rate <
System Clock
Maximum Cycles in Compare Interrupt
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
Figure 3-1. UART Counter Values
1
3
5
7
9
11
13
15
17
Start
Bit
D0
D1
D2
D3
D4
D5
D6
D7
21
19
23
Reception
Stop
Bits
Transmission
2
4
6
8
10
12
14
16
18
20
22
3.5 UART functions
The driver consists of three global functions:
void
SW_UART_Enable(void)
void
SW_UART_Transmit(uint8_t)
uint8_t
SW_UART_Receive(void)
The SW_UART_status is a global variable holding the UART status flags. The
SET_FLAG, CLEAR_FLAG and READ_FLAG macros can be used to access the
status flags defined in single_wire_UART.h.
The following interrupts routines are used in the UART implementation:
__interrupt void External_SW_UART_ISR()
__interrupt void Timer_Compare_SW_UART_ISR()
The next section contains brief descriptions and flowcharts for the UART functions:
3.5.1 SW_UART_Enable
Before data can be received or transmitted the UART needs to be enabled by calling
the SW_UART_Enable function. It tri-states the UART pin so the line is idle high. The
status register and counter is cleared so all ongoing transmissions are stopped.
Disabling the external and timer interrupt will stop the UART.
6
AVR274
8065A-AVR-03/07
AVR274
Figure 3-2. SW_UART_Enable() function
SW UART Enable
Set bus idle high
Initialize UART
external interrupt
Clear status
register
Clear external
interrupt flag
Set state IDLE
Enable external
interrupt
Return
3.5.2 SW_UART_Transmit
The SW_UART_Transmit() function takes one byte as parameter and adds this byte
to the transmit buffer. The SW_UART_TX_BUFFER_FULL flag must be zero when
calling this function, or else data will be lost. If a data transfer is not in progress when
this function is called, a new transmission will be started by sending a start bit and
enabling the timer interrupt.
7
8065A-AVR-03/07
Figure 3-3. SW_UART_Transmit() function
SW UART
Transmit (data)
Set Tx data buffer
full flag
Yes
Copy Tx buffer to
Tx data
Copy data to Tx
buffer
Clear Tx buffer full
flag
counter = 0?
Disable external
interrupts
Send start bit
counter = 2
Clear timer
Set timer compare
= start transmit
No
Clear timer
interrupt flag
Enable UART
timer interrupt
Start timer
Return
3.5.3 SW_UART_Receive
This function returns the byte received in Rx_data. The UART_RX_BUFFER_FULL
flag must be checked before calling this function to make sure there is valid data in
Rx_data. When receiving multiple bytes it is important to call this function before next
byte is received, or else the receive buffer will be overflowed and data lost.
8
AVR274
8065A-AVR-03/07
AVR274
Figure 3-4. SW_UART_Receive() function
SW UART
Receive
Copy content of
RX_buffer to data
Clear Rx buffer full
flag
Return data
3.5.4 SW_External_UART_ISR
The External_SW_UART_ISR() is triggered when a falling edge is detected on the
line when there is no ongoing transmission or reception. The routine checks if the
UART pin is low. If not, no reception is started. It also disables further external
interrupts so no falling edges on the data bits will trigger a new interrupt, as it is only
used to detect the start bit.
Figure 3-5. External_SW_UART_ISR()
UART External
ISR
Yes
UART pin low?
Set counter = 3
Clear Rx data
Set UART timer
compare = start
receive
No
Clear UART timer
interrupt flag
Enable UART
timer interrupt
Clear UART timer
Return
3.5.5 Timer_Compare_SW_UART_ISR
The Timer_Compare_SW_UART_ISR() (Figure 3-1) controls the handling for
transmitting and receiving frames. It is called automatically when the output compare
register equals the timer and the UART timer interrupt is set. Data is transmitted when
the UART counter is even, and received when the counter is odd. The receive (Figure 3-8) and transmit handler (Figure 3-7) is implemented directly into the timer
interrupt. Please refer to Figure 3-1 for details on the different counter values.
9
8065A-AVR-03/07
Figure 3-6. Timer_Compare_SW_UART_ISR()
UART Timer
Compare ISR
Set line value =
bit_in
UART counter
is odd=?
Yes
No
UART
Transmit
Handler
UART
Receive
Handler
Increment UART
counter by 2
Return
10
AVR274
8065A-AVR-03/07
AVR274
Figure 3-7. UART Transmit Handler()
UART Transmit
Handler
UART
counter != 2?
Yes
Set last_bit_sent
=1
No
UART
counter <= 16?
Yes
UART
counter <= 18?
Yes
Set last_bit_sent
= Tx data & 0x01
No
UART
counter = 18 ?
Right shift
UART_Tx_data
Yes
No
UART
counter = 20?
Set frame error
flag if last_bit_sent
!= bit_in
Clear external
interrupt flag
Enable external
interrupt
Tx buffer full
flag set ?
No
Set bit_out = 1
Yes
Copy Tx buffer to
Tx data
Clear Tx buffer full
flag
Set UART counter
=0
Set bit_out
according to
Tx_data
Stop timer
Disable timer
interrupt
Set UART counter
=0
Set bit_out = 0
Disable external
interrupt
Exit interrupt
Set UART pin
according to
bit_out
Return
11
8065A-AVR-03/07
Figure 3-8. UART Receive Handler()
UART Receive
Handler
UART
counter <= 17?
Yes
No
Right shift Rx data
UART
counter = 19?
Yes
Update Rx data
according to bit_in
No
Set frame error if
bit_in == 0
UART
counter = 23?
Tx buffer
full flag set?
No
Copy Tx buffer to
Tx data
Set Rx buffer
overflow flag if Rx
buffer full flag is
set
Stop timer
Clear Tx buffer
full flag
Copy Rx data to
Rx buffer
Disable UART
external interrupt
Set Rx buffer full
flag
Send start bit
Clear external
interrupt flag
Set UART
counter = 0
Disable UART
timer interrupt
Yes
Set UART
counter = 2
Enable external
interrupt
Clear timer
Set timer compare
= start transmit
Clear timer
interrupt flag
Exit interrupt
Return
3.6 Example Program
The main.c contains an example program for testing the UART. It receives data to a
byte array and transmits the data back when the array is full or when a return
character is received.
12
AVR274
8065A-AVR-03/07
AVR274
3.7 Code Size
When complied with IAR® EWAVR 4.21A and maximum speed optimization turned
on the code size for the UART driver is 500 bytes.
4 Getting Started
The source code can be downloaded as a zip-file from www.atmel.com/avr. The code
is written for the ATmega32 and complied using the IAR EWAVR 4.20A complier. To
compile the source without any changes the IAR EWAVR complier is needed.
Doxygen documentation is available in readme.html.
13
8065A-AVR-03/07
Disclaimer
Headquarters
Operations
Atmel Corporation
Memory
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 487-2600
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 436-4314
Microcontrollers
International
Atmel Asia
Room 1219
Chinachem Golden Plaza
77 Mody Road Tsimshatsui
East Kowloon
Hong Kong
Tel: (852) 2721-9778
Fax: (852) 2722-1369
Atmel Europe
Le Krebs
8, Rue Jean-Pierre Timbaud
BP 309
78054 Saint-Quentin-en-Yvelines
Cedex
France
Tel: (33) 1-30-60-70-00
Fax: (33) 1-30-60-71-11
Atmel Japan
9F, Tonetsu Shinkawa Bldg.
1-24-8 Shinkawa
Chuo-ku, Tokyo 104-0033
Japan
Tel: (81) 3-3523-3551
Fax: (81) 3-3523-7581
2325 Orchard Parkway
San Jose, CA 95131, USA
Tel: 1(408) 441-0311
Fax: 1(408) 436-4314
La Chantrerie
BP 70602
44306 Nantes Cedex 3
France
Tel: (33) 2-40-18-18-18
Fax: (33) 2-40-18-19-60
ASIC/ASSP/Smart Cards
RF/Automotive
Theresienstrasse 2
Postfach 3535
74025 Heilbronn
Germany
Tel: (49) 71-31-67-0
Fax: (49) 71-31-67-2340
1150 East Cheyenne Mtn. Blvd.
Colorado Springs, CO 80906, USA
Tel: 1(719) 576-3300
Fax: 1(719) 540-1759
Biometrics
Avenue de Rochepleine
BP 123
38521 Saint-Egreve Cedex
France
Tel: (33) 4-76-58-47-50
Fax: (33) 4-76-58-47-60
Zone Industrielle
13106 Rousset Cedex
France
Tel: (33) 4-42-53-60-00
Fax: (33) 4-42-53-60-01
1150 East Cheyenne Mtn. Blvd.
Colorado Springs, CO 80906, USA
Tel: 1(719) 576-3300
Fax: 1(719) 540-1759
Scottish Enterprise Technology Park
Maxwell Building
East Kilbride G75 0QR
Scotland
Tel: (44) 1355-803-000
Fax: (44) 1355-242-743
Literature Requests
www.atmel.com/literature
Disclaimer: The information in this document is provided in connection with Atmel products. No license, express or implied, by estoppel or otherwise, to any
intellectual property right is granted by this document or in connection with the sale of Atmel products. EXCEPT AS SET FORTH IN ATMEL’S TERMS AND
CONDITIONS OF SALE LOCATED ON ATMEL’S WEB SITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED
OR STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the accuracy or completeness of the
contents of this document and reserves the right to make changes to specifications and product descriptions at any time without notice. Atmel does not make any
commitment to update the information contained herein. Unless specifically provided otherwise, Atmel products are not suitable for, and shall not be used in,
automotive applications. Atmel’s products are not intended, authorized, or warranted for use as components in applications intended to support or sustain life.
© 2007 Atmel Corporation. All rights reserved. Atmel®, logo and combinations thereof, Everywhere You Are®, AVR®, and others, are the
registered trademarks or trademarks of Atmel Corporation or its subsidiaries. Other terms and product names may be trademarks of others.
8065A-AVR-03/07