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 AVR Boards 1.8.6

License

 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
/*
  Copyright (c) 2019 garretlab.
  Added source code explanation by garretlab.
*/

/*
  HardwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

  Modified 23 November 2006 by David A. Mellis
  Modified 28 September 2010 by Mark Sproul
  Modified 14 August 2012 by Alarus
  Modified 3 December 2013 by Matthijs Kooijman
*/

Last Update

August 25, 2019

inserted by FC2 system