Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
_rx_complete_irq()

_rx_complete_irq()

概要

_rx_complete_irq()は、シリアル通信でデータを受信したときに起動される割り込みハンドラの、USART_RX_vectから呼び出され、ATmega328Pの受信バッファからArduinoの受信バッファにデータを移動します。

ソースコード

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

void HardwareSerial::_rx_complete_irq(void)
{
  if (bit_is_clear(*_ucsra, UPE0)) {
    // No Parity error, read byte and store it in the buffer if there is
    // room
    unsigned char c = *_udr;
    rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;

    // if we should be storing the received character into the location
    // just before the tail (meaning that the head would advance to the
    // current location of the tail), we're about to overflow the buffer
    // and so we don't write the character or advance the head.
    if (i != _rx_buffer_tail) {
      _rx_buffer[_rx_buffer_head] = c;
      _rx_buffer_head = i;
    }
  } else {
    // Parity error, read byte but discard it
    *_udr;
  };
}

入力はありません。戻り値もありません。

void HardwareSerial::_rx_complete_irq(void)
{

bit_is_clear()で、_ucsra(UCSR0A)レジスタのUPE0が0かどうかを判定します。0のときはパリティエラーがない状態なので、データを読み込みます。

  if (bit_is_clear(*_ucsra, UPE0)) {
    // No Parity error, read byte and store it in the buffer if there is
    // room
    unsigned char c = *_udr;
    rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;

    // if we should be storing the received character into the location
    // just before the tail (meaning that the head would advance to the
    // current location of the tail), we're about to overflow the buffer
    // and so we don't write the character or advance the head.
    if (i != _rx_buffer_tail) {
      _rx_buffer[_rx_buffer_head] = c;
      _rx_buffer_head = i;
    }

_udr(UDR0)は、受信したデータが入っているレジスタです。

_rx_buffer_headは、最新の受信データが格納されている位置を示す変数です。今回受信するデータはその次の場所に格納するため、1を足しています。

受信バッファはリングバッファなので、バッファの最後に到達したときには先頭に戻します。このため、tailに1を足した後、バッファのサイズ(SERIAL_RX_BUFFER_SIZE)で割った余りを代入しています。

今回取得した格納位置(i)が_rx_buffer_tail(最も古い未読み出しのデータが格納されている位置)に到達していないときは、バッファにデータを格納し、_rx_buffer_headを更新します。

  } else {
    // Parity error, read byte but discard it
    *_udr;
  };
}

パリティエラーが発生したときは、_udrを読み出し、何もせずに破棄します。

バージョン

Arduino 1.8.3



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

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