Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
Serial.begin()/HardwareSerial::begin()

HardwareSerial::begin()

概要

HardwareSerial::begin()は、シリアル通信を行う際の通信速度の設定や送受信の許可ビットの設定を行います。リファレンスはこちら

HardwareSerial::begin()では、UCSR0AUCSR0BUSCR0CUBRR0H、UBRR0Lの5つのレジスタを操作します。

ソースコード

HardwareSerial::begin()は、hardware/arduino/cores/arduino/HardwareSerial.cppに定義されています。以下に全ソースコードを示します。

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);
}

入力はbaudとconfigで、型はそれぞれunsigned longとbyteです。戻り値はありません。

baudは、通信速度(bps)です。

configはシリアル通信のデータ長とパリティ、ストップビットを設定します。この引数は明示的に与える必要はなく、この場合はデフォルトではSERIAL_8N1(8ビット・パリティビットなし・ストップビット1)が設定されます。

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;

baud_settingは、UBRR0H/UBRR0Lに設定する値です。UCSR0AのU2X0ビットとの組み合わせで、通信速度が決まります。まずは、UCSR0AのU2X0ビットを1にした時の値を計算します。

通信速度(baud)とUBRR0H/UBRR0Lに設定する値の関係は以下の通りです。

  1. U2X0 = 0のとき
    URBR0 = (F_CPU / (16 * BAUD)) - 1
  2. U2X0 = 1のとき
    URBR0 = (F_CPU / (8 * BAUD)) - 1

しかし、Arduinoでは、以下のように設定しています。

  1. U2X0 = 0のとき
    UBRR0 = (F_CPU / 8 / baud - 1) / 2
  2. U2X0 = 1のとき
    UBRR0 = (F_CPU / 4 / baud - 1) / 2

このため、データシートに記載の値よりも0.5だけ大きい値を設定することになりますが、UBRR0は整数なので基本的には同じ数値になるようです。

  // 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;
  }

F_CPUが16000000(16MHz)でbaudが57600の場合は、Duemilanoveなどのブートローダとの互換のため、あるいは、最初に算出したbaud_settinが4095を超えるときは、UBRR0の有効ビット数がが12ビットなので、U2X0を0にして、baud_settingを再計算します。baud_settingが4095より大きくなるのは、baudが488以下の場合です。

  // assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
  *_ubrrh = baud_setting >> 8;
  *_ubrrl = baud_setting;

  _written = false;

次に、計算したbaud_settingをUBRR0レジスタに設定します。上位4ビットをUBRR0Hに、下位8ビットをUBRR0Lに代入します。

その後、_writtenをfalseに設定します。_writtenの初期値はfalseで、一度でも送信バッファに書き込みを行うとtrueに設定します。この値は、flushするときに利用します。

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

次に、configをUCSR0Cに設定します。UCSR0Cは、パリティやストップビットの設定を行うためのレジスタです。

  sbi(*_ucsrb, RXEN0);
  sbi(*_ucsrb, TXEN0);
  sbi(*_ucsrb, RXCIE0);
  cbi(*_ucsrb, UDRIE0);
}

最後に、UCSR0Bレジスタの設定を行います。USARTの受信許可(RXEn)、送信許可(TXEn)、RXCnフラグの割り込み許可(RXCIEn)、UDRIEnの割り込み禁止(UDRIEn)に設定します。sbi()は、第1引数の、第2引数ビット目を1に、cbi()は、第1引数の、第2引数ビット目を0に設定します。

バージョン

Arduino 1.8.3



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2017 garretlab all rights reserved.
inserted by FC2 system