Opening Channels of
Since we’re working with an eight-bit microcontroller with
eight-bit registers, we can’t squeeze 12 bits into the
register. So, we need to split the value over two registers
(well, one and a half technically, but we leave the
remaining four bits unused): the USART baud tate Low
and High registers: UBRR0L (low) and UBRR0H (high).
We’ve now finished the background we needed to
cover in order to get stuck in. Last month, we had our first
dealings with registers that weren’t linked to I/O pins. We
used a host of bizarre acronym-like register names to
configure our ADC. This month, we’re going to need to
do something similar as we configure our UART.
We’ll need to apply exactly the same practices that
we did last month — so pull out the datasheet and turn to
section 20. 11 which describes the USART registers. If you
need to remind yourself of the way that we configure the
registers using macros and bit-shifting, then do a quick
read-over of last month’s article. I’ve just poured myself a
fresh cup of coffee, so here goes!
As an example, let’s assume we’re running on a 16
MHz crystal and want to set a baud rate of 2400 (very
slow, but it works well for this illustration). From the table
in Figure 2, we need a UBRRn value of 416. Assuming we
store this value in the variable baudRegValue, the code to
set the registers looks like this:
UBRR = F_CPU / 16 / BAUD ——1
unsigned long baudRegValue = 416;
UBRR0H = (unsigned char)(baudRegValue>>8);
UBRR0L = (unsigned char)baudRegValue;
Configuring the UART
From the background discussions on the various
options we can choose when framing our data, you’ve
probably already guessed that we need to let our UART
module know how we want to communicate over the
serial line. This configuration needs to be performed on
both the transmitting device and the receiving device —
and you’ve probably guessed that they need to use the
same settings (otherwise, the devices will literally be
talking past each other).
You’ll recognize the “>>” symbol above as a right-shift
— the opposite direction to what we normally use when
setting values in registers. To see how this works under the
hood, refer to the sidebar, Shifting Left, Shifting Right.
Okay, we’ve set the baud rate. On to the next set of
options (and yes, these are simpler).
Step 2: Set the Frame — Data Bits
The UART on the ATmega328P supports between five
and nine bits. As I haven’t yet needed to particularly
optimize the serial communication on my projects, I stick
with eight bits as it’s easier to work with (and also
happens to be the default on most terminal programs).
The flowchart in Figure 3 gives an overview of the
whole process; let’s start by focussing on the red portions.
To configure eight or less data bits, we work with the
UCSR0C (USART Control and Status Register C), bits 1
Step 1: Set the Baud Rate
Setting the baud rate isn’t as simple as just passing the
chosen value into the microcontroller’s register. The baud
rate that the UART runs at is linked to the speed you’re
running your microcontroller at. You are the one who
needs to take this into account — the microcontroller
doesn’t! This means you need to calculate the value using:
• UBRR is the value we need to pass to the register
• F_CPU is the MCU speed (e.g., 16000000 if we’re
running at 16 MHz)
• BAUD is the baud rate you want to run at (e.g.,
Alternatively, you can cheat — perhaps that’s too
strong a word — short-cut the process and refer to the
baud rate tables in the datasheet (see Figure 2).
Remember the UBRRn column we mentioned earlier?
Well, this conveniently gives you the value you need to set
the register to. Easy, right? Well, not quite.
To set the baud rate, we need to work with two
registers: UBRR0L and UBRR0H. Why two registers? The
range of possible UBRR values means that we need to use
12 bits to pass this information onto the microcontroller.
June 2015 59
Figure 3: Flowchart outlining basic UART-related