A simplified block diagram of the USART Transmitter is shown in following figure. CPU accessible I/O
Registers are shown with green boxes, and I/O pins are shown in blue boxes. The USART Data Register UDR is shown in yellow boxes. Please note that altough shown as two boxes in diagram below, there is only one UDR register which functioned as register for holding either received byte / byte to be transmitted.
On diagram above, you'll notice on the top block is Clock Generator section. This section conduct the whole orchestra of USART operations. It generates the base clock for the Transmitter and Receiver.
There are four modes of clock operations:
- Normal Asynchronous mode
- Double Speed Asynchronous mode
- Master Synchronous mode
- Slave Synchronous mode
To select Asynchronous mode, clear UMSEL bit in
UCSRC (
USART Control and Status Register C). In other hand, set UMSEL bit to select Synchronous mode.
To activate Double Speed Asynchronous mode, after clearing the UMSEL bit (to set USART into Async mode), set the U2X bit of
UCSRA register. Clearing the U2X bit bring back USART to normal Async mode. For synchronous mode, this bit has no effect and should be cleared.
For Synchronous mode (UMSEL=1), data is clocked in sync with
XCK
pin (
PD.4, pin#6 of ATmega328). In this case, value of DDR_XCK (
Data Direction Register for XCK Pin) determine whether the clock source is internal (Master mode, MCU is the one who generate clock signal into
XCK
pin) or external (Slave mode, MCU is following clock signaled on
XCK
pin from other party). The
XCK
in is only active when using Synchronous mode. Please note that while in Sync mode, since
PD.4
is shared the same physical pin as
XCK
(pin#6), it's no longer functioned as General I/O pin.
Except for Synchronous Slave Mode, all other modes requires the MCU to generate clock signal. This is done internally by Clock Generator section (refer back to block diagram above).
As shown in the diagram, register related to this section is
UBRR
, acronym for
USART Bit Rate Register. It's actually a 12-bit register, thus it's divided into two byte:
UBRRH register for the high-byte (note that only lower nibble of this register is being used) and
UBRRL register for the low-byte.
Following is detailed block diagram of Clock Generator section:
The
UBRR and the down-counter connected to it function as a programmable prescaler or baud rate generator. The down-counter, running at system clock (
fosc), is loaded with the
UBRR value each time the counter has counted down to zero or when the lower byte (
UBRRL) Register is written. A clock is generated each time the counter reaches zero. This clock is the baud rate generator clock output, equal to
fosc / (UBRR+1).
The Transmitter divides the baud rate generator clock output by 2, 8, or 16 depending on mode being selected. The baud rate generator output is used directly by the Receiver's clock and data recovery units. However, the recovery units use a state machine that uses 2, 8, or 16 states depending on mode set by the state of the UMSEL, U2X and DDR_XCK bits (examine flow logic shown by arrow lines on the diagram).
Following table constains equations for calculating the baud rate (in bits per second) and for calculating the UBRR value for each mode of operation using an internally generated clock source:
BAUD = Baud rate (in bits per second, bps)
fosc = System Oscillator clock frequency
UBRR = Contents of
UBRRH and
UBRRL Registers (12 bits, 0-4095)
Thus for
fosc = 16 MHz (frequency of oscillator used in Arduino Uno), we can calculate the value of
UBRR on Async Double Speed Mode (U2X=1) by formula:
UBRR
= ( 16,000,000 / 8*BAUD ) - 1
= ( 2,000,000 / BAUD ) - 1
According to this equation, following is the value for common baud rates (
Error Margin on the third row is rounding error caused by rounding a float number into it's corresponding integer value):
Baud Rate | 2400 | 4800 | 9600 | 14.4K | 19.2K | 28.8K | 38.4K | 57.6K | 115.2K | 250K |
UBBR Value | 832 | 416 | 207 | 138 | 103 | 68 | 51 | 34 | 16 | 7 |
Error Margin | — | -0.1% | 0.2% | -0.1% | 0.2% | -0.6% | 0.2% | -0.8% | 2.1% | — |