Reconfigurable computing
Small Embedded Systems
Unit 4.3 Controlling the UART using Special Function Registers
Introduction
Baud rate generation
Controlling asynchronous transfers using special function registers
Baud Rate Generator
Divides microcontroller master clock by an appropriate amount to get the baud rate needed by the UART
Division ratio is determined by value n stored by software in a register
To avoid huge values for n, there is also a selectable pre-divider that applies standard scaling ratio
(For Atmega328P, the available ratios are 2, 8, 16,…)
Example: suppose clock is 16 MHz
We want a baud rate of 9600 baud
How does the UART do that?
Pre-divider
Divide by n+1
Master clock
Baud rate clock
Baud Rate Generator
Example: suppose clock is 16 MHz
We want a baud rate of 9600 baud
Select pre-divider ratio of 16 (biggest available for Atmega 328)
We set a value of n in the register that controls baud rate
n = 103 = 0x67
This gives us a baud rate of 9615
Baud rate error is 0.16% – this is tolerable
Pre-divider
Divide by n+1
Master clock
Baud rate clock
so
Baud Rate Generator
The 16-bit value of n is stored in a pair of 8-bit control registers UBRRH and UBRRL
Another control register UCSR (USART control and status register) sets the mode through a bit called U2X
Pre-divider
Divide by n+1
Master clock
Baud rate clock
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
Baud Rate Error Tables
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
UART manufacturers supply standard tables of values for n and the resulting baud rate error:
ATmega328P USART Block Diagram
Control/Status registers
Individual bits set:
Word length
Parity
TX enable
UX enable
Mode …
Sets value of n that controls Baud rate
Data sheet shows 5 registers that control USART
Also, 1 data register used for transmit/receive byte
ATmega328P Data Sheet
Address
Name
Size
Bits
Control
Data
Writing appropriate values to the bits in control registers will set baud rate
U2X0 double speed flag (sets pre-divider ratio)
UBRR value of counter for Baud rate generation
For example, to set 9600 baud from a 16 MHz clock:
Set UBRR0H to 0x00 and UBRR0L to 0x67
ATmega328P Data Sheet : Baud Rate
Address
Name
Size
Bits
ATmega328P Data Sheet: Word Format
Address
Name
Size
Bits
Values to set 8-N-1
ATmega328P Data Sheet: TX/RX
Address
Name
Size
Bits
TX: transmit enable
RX: receive enable
TXC0: a transmit operation has been completed
RXC0: a receive operation has been completed
TXB/RXB: buffer for 8-bit transmit/receive data
TXB80: if 9-bit data is used, the extra bit is stuffed here
Coding Asynchronous Setup
High level code (Arduino IDE):
void setup() {
Serial.begin(9600);
}
Default format is 8-N-1
void setup() {
Serial.begin(9600, SERIAL_7E1);
}
void setup() {
Serial.begin(9600, SERIAL_8O1);
}
void setup() {
Serial.begin(9600, SERIAL_8N1);
}
Coding Asynchronous Setup
High level code (Arduino IDE):
Low level code: directly set USART registers:
void Setup() {
serial.begin(9600);
}
Default format is 8-N-1
void USART_Init( uint8_t ubrr) {
/*Set baud rate */
UBRR0H = 0;
UBRR0L = ubrr;
/* Enable receiver and transmitter */
UCSR0B |= (1<