Playing with Arduino
A page to record my playing with Arduino
HardwareSerial::begin()

Abstract

The HardwareSerial::begin() sets theg communication speed and other settings.

To meet the purpose, the HardwareSerial::begin() sets UCSR0A, UCSR0B, UCSR0C, UBRR0H and UBRR0L.

Source Code

The HardwareSerial::begin() is defined in hardware/arduino/cores/arduino/HardwareSerial.cpp as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void HardwareSerial::begin(unsigned long baud, byte config)
{
  // Try u2x mode first
  uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
  *_ucsra = 1 << U2X0;
 
  // hardcoded exception for 57600 for compatibility with the bootloader
  // shipped with the Duemilanove and previous boards and the firmware
  // on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
  // be > 4095, so switch back to non-u2x mode if the baud rate is too
  // low.
  if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
  {
    *_ucsra = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }
 
  // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
  *_ubrrh = baud_setting >> 8;
  *_ubrrl = baud_setting;
 
  _written = false;
 
  //set the data bits, parity, and stop bits
  *_ucsrc = config;
   
  sbi(*_ucsrb, RXEN0);
  sbi(*_ucsrb, TXEN0);
  sbi(*_ucsrb, RXCIE0);
  cbi(*_ucsrb, UDRIE0);
}

The input is baud and config, their type are unsigned long and byte respectively.

The baud means communication speed in bps.

The config sets data length, parity, and stop bit. If this argument is omitted, SERIAL_8N1(8bit, no parity, stop bit 1) is used.

1
2
3
4
5
void HardwareSerial::begin(unsigned long baud, byte config)
{
  // Try u2x mode first
  uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
  *_ucsra = 1 << U2X0;

The baud_setting is the value to set to UBRR0H/UBRR0L. With the combination of U2X0 bit in UCSR0A, the speed is determined.

First, it calculates with U2X0 bit on.

According to the data sheet, the communication speed(baud) is defined as below.

In case of U2X0 = 0
URBR0 = (F_CPU / (16 * BAUD)) - 1
In case of U2X0 = 1
URBR0 = (F_CPU / (8 * BAUD)) - 1

But the Arduino software sets it as below.

In case of U2X0 = 0
UBRR0 = (F_CPU / 8 / baud - 1) / 2
In case of U2X0 = 1
UBRR0 = (F_CPU / 4 / baud - 1) / 2

So it would become 0.5 greater than specification, but the UBRR0 is an integer, it would be the same.

 7
 8
 9
10
11
12
13
14
15
16
// hardcoded exception for 57600 for compatibility with the bootloader
// shipped with the Duemilanove and previous boards and the firmware
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
// be > 4095, so switch back to non-u2x mode if the baud rate is too
// low.
if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
{
  *_ucsra = 0;
  baud_setting = (F_CPU / 8 / baud - 1) / 2;
}

If F_CPU is 16000000(16MHz) and baud is 57600, or baud_setting is greater than 4095(when the baud is less than or equal to 488), sets the U2X0 to 0 and calculate it again.

18
19
20
21
22
// assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
 
_written = false;

Sets the calculated baud_setting to UBRR0. Upper 4 bits to UBRR0H and lower 8 bits to UBRR0L.

Then sets the _written to false. Once we write data to the transmit buffer, it becomes true. The value is used in HardwareSerial::flush().

24
25
//set the data bits, parity, and stop bits
*_ucsrc = config;

Next, sets config to UCSR0C. It is the register to set parity , stop bit and so on.

27
28
29
30
31
  sbi(*_ucsrb, RXEN0);
  sbi(*_ucsrb, TXEN0);
  sbi(*_ucsrb, RXCIE0);
  cbi(*_ucsrb, UDRIE0);
}

Finally sets UCSR0B register. sbi() is a function to set the second argument bit of the first argument to 1. cbi() sets to 0.

Version

Arduino 1.8.13

Last Update

June 19, 2020

inserted by FC2 system