Arduinoで遊ぶページ

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

Serial.write()/HardwareSerial::write()

概要

Serial.write()/HardwareSerial::write()は、バイナリデータをシリアルポートに書き込みます。リファレンスはこちら

ソースコード

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

size_t HardwareSerial::write(uint8_t c)
{
  int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
        
  // If the output buffer is full, there's nothing for it other than to 
  // wait for the interrupt handler to empty it a bit
  // ???: return 0 here instead?
  while (i == _tx_buffer->tail)
    ;
        
  _tx_buffer->buffer[_tx_buffer->head] = c;
  _tx_buffer->head = i;
        
  sbi(*_ucsrb, _udrie);
  // clear the TXC bit -- "can be cleared by writing a one to its bit location"
  transmitting = true;
  sbi(*_ucsra, TXC0);
  
  return 1;
}

入力はuint8_tで、戻り値はsize_tです。

size_t HardwareSerial::write(uint8_t c)
{

送信バッファ内の次にデータを書き込む場所を求めます。

  int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;

SERIAL_BUFFER_SIZEで割った余りを求めているのは、送信バッファがリングバッファで、バッファの最後に到達したときに先頭に戻すためです。

今求めた場所がtailと等しくなくなるまでループして待ちます。

  // If the output buffer is full, there's nothing for it other than to 
  // wait for the interrupt handler to empty it a bit
  // ???: return 0 here instead?
  while (i == _tx_buffer->tail)
    ;

headとtailが同じ場合は、書き込む場所がないため、バッファが空くのを待ちます。

バッファに引数で与えられたデータを書き込み、headを一つ進めます。

  _tx_buffer->buffer[_tx_buffer->head] = c;
  _tx_buffer->head = i;

UDREnフラグ割り込みを許可することで、シリアルデータの送信を可能とします。transmittingをtrueにした後、UCSRAのTXC0ビットを1に設定します。1を設定すると0になります。

  sbi(*_ucsrb, _udrie);
  // clear the TXC bit -- "can be cleared by writing a one to its bit location"
  transmitting = true;
  sbi(*_ucsra, TXC0);

レジスタの説明はこちらをご覧ください。実際にデータを送信するのは、USART_UDRE_vectという割り込みベクタで行います。

最後に1(=書き込んだバイト数)を返します。

  return 1;
}

バージョン

Arduino 1.0.5



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

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