Skip to content

HarfUART

朝日薫 edited this page Dec 19, 2022 · 15 revisions

HarfUART クラスリファレンス

最小フットプリントの、二線式半二重UART通信HarfUART_Class基本クラス。 Arduino互換APIの<HardwareSerial.h>を代替する。 プロトコルは 8N1 専用。 割込も計時器周辺機能もFIFOバッファも使用しない。 従って全体割り込み禁止中でも、割込ハンドラの中からでも使用できる。

reduceAVR は未対応

有効ならENABLE_CLASS_HARFUARTマクロに1が定義される。

クラスインスタンスはスケッチ.inoでは自動で設定され、無宣言で使用できる。 そうでなければ<peripheral.h>{build.variant}に置かれている) をインクルードすることで準備される。

用例

/* #include <peripheral.h> */   /* *.ino 以外 */
void setup (void) {
  Serial.begin(CONSOLE_BAUD);   /* {build.console_baud} */
}
void loop (void) {
  if (Serial.available()) Serial.write( Serial.read() );
}

<api/HarfUART.h>

依存性:<avr/io.h> <Portmux.h> <UsartBaseClass.h> <peripheral.h>

#define Serial Serial0

デフォルトインスタンスを指すSerialは通常、Serial0を指すエイリアスである。 更にSerial0は普通Serial0Aを指すように定義されている。 Serialはボードサブメニューやブートローダー選択に応じて Arduino IDE によって書換えられる。

<peripheral.h>で定まる事前定義は次のようになっている。 対応する TX/RX 入出力外部端子ペアは一意に決まっているので、 そのバリアントで使えない定義は存在しない。 定義されていても実体が使われないインスタンスは 最終出力 HEX/bin には書き出されない。

#ifndef Serial                  /* {build.console_select} がない場合 */
#define Serual Serial0          /* 代表エイリアス */
#endif

#define Serial0 Serial0A
#define Serial1 Serial1A
#define Serial2 Serial2A
/* ~ */
/* インスタンス宣言 */
HarfUART_Class Serial0A {&USART0, &_portmux_usart0a}; /* USART0_DEFAULT */
HarfUART_Class Serial0B {&USART0, &_portmux_usart0b}; /* USART0_ALT_1 */
HarfUART_Class Serial0C {&USART0, &_portmux_usart0c}; /* USART0_ALT_2 */
/* ~ */

/* 実際に参照したインスタンスだけが最終バイナリに結合される */
Serial.begin(CONSOLE_BAUD);

プライマリが0、以後追加ポート以降に1 2... の識別子が付く。
PORTMUX の DEFAULT選択がA、ALTERNATE_1がB、以後C D... の接尾子が付く。
インスタンスが複数あっても同一周辺機能なら同時使用できないことに注意。

どの型番でどの周辺機能が使用できるかは [modernAVR 周辺機能比較一覧] を参照のこと。

HarfUART_Class& HarfUART_Class::begin (const uint32_t _baudrate)

UARTの使用を、任意のボーレート値で開始する。 自身のオブジェクトを返すので、メソッドチェーンを後続できる。 ボーレート値から実際に必要な設定値を計算してinitiate()を呼び出すため、 事前コンパイル済定数を与えないと除算ライブラリが結合されることに注意。

Serial.begin(CONSOLE_BAUD);

F_CPUによって動作可能速度が定まるため、計算範囲外となる値では正常動作しない。 CPU主クロックは設定ボーレートの 8倍以上 8192倍未満でなければならない。 ただし限界付近ではマージンが不足するため安定しない。

HarfUART_Class& HarfUART_Class::initiate (const uint16_t _baudrate)

UARTの使用を、指定の定数ラベルで開始する。 自身のオブジェクトを返すので、メソッドチェーンを後続できる。 定数ラベルは<Portmux_private.h>で事前計算され定義されている。 除算は使われない。

Serial.initiate(UART_115200);
/* etc */
Serial.initiate(UART_CONSOLE_BAUD);

F_CPUによって動作可能速度は定まるため、計算範囲外となる定数ラベルは定義されない。

UART_CONSOLE_BAUDは事前定義マクロCONSOLE_BAUDを元に生成されるが、 OSC-ULP 動作時は最大 2400bps、1200bps、あるいは 300bps の設定で上書きされるだろう。 F_CPU が 2400 未満では、Arduino IDE のシリアルコンソール(下限300bps)とは通信できない。

void HarfUART_Class::end (void)

UART装置の使用を停止し、専有していた外部端子を開放する。 RX線の内蔵プルアップも無効になる。

  • 一般に、UART対向機器の電源が落ちている場合は TX線が Hi-Zか LOWになるだろう。 これを調べるには TX端子をデジタル入力許可に変えなければならない。 end()後はそれが可能な状態になる。

size_t HarfUART_Class::write (const uint8_t _c)

1キャラクタを出力する。 送信緩衝バッファが空いていなければ空くまで待つ。 常に1を返す。 全体割込が禁止されていても動作する。

size_t HarfUART_Class::write (const uint8_t* _buffer, size_t _length)

指定のバッファから指定の量を書き出す。書けた量を返す。 全体割込が禁止されていても動作する。

int HarfUART_Class::read (void)

1キャラクタを入力する。 入力が空かフレームエラーがあれば -1 を返す。 全体割込が禁止されていても動作するが、 他の割込動作が2キャラクタ時間(20bit相当)以上継続すると、その間の入力は失われる。

size_t HarfUART_Class::readBytes (void* _buffer, size_t _limit, char _terminate = 0, uint8_t _swevent = 0)

指定の_bufferに、最大_limit文字数、 あるいは_terminate指定キャラクタ出現までを取得する。取得されたキャラクタ数を返す。 _bufferの最後に\0は補完されないことに注意。

_terminate指定キャラクタは取得内容に含まれる。しかし\0は指定できない。 受信キャラクタが\0であればそれは含まれる。 そしてBREAK と見做して受信待機を打ち切るだろう。

このメソッドが呼ばれると、少なくとも12bit時間のあいだ通信線を監視して IDLE 状態が続いたなら何も取得せずに終了し0を返す。

つまりNOBLOCK動作であるから、必要に応じて繰り返し呼び出さなければならない。

_swevent0以外であるなら、それは事象システム EVSYS ストローブ指令と解釈され、 最初の受信キャラクタ検出の瞬間に以下の IOレジスタへ代入し、 任意の事象イベントを発火することが出来る。

tinyAVR-0/1 megaAVR-0 その他のmodernAVR
EVSYS_ASYNCSTROBE EVSYS_STROBE EVSYS_SWEVENTA

発火イベントが割込を惹起する場合はそちらの実行が優先され、そして受信落ちを経験するだろう。 だが全体割込禁止中でもこのメソッドが機能することは留意されたい。

size_t HarfUART_Class::available (void)

受信緩衝バッファに1キャラクタが揃っていれば(read可能なら)1を返す。 そうでなければ0を返す。 全体割込が禁止されていても動作するが、 他の割込動作が2キャラクタ時間(20bit相当)以上継続すると、その間の入力は失われる。

size_t HarfUART_Class::availableForWrite (void)

送信緩衝バッファが空いていれば(待たずにwrite可能なら)1を返す。 空いていなければ(送信待機中であれば)0を返す。 全体割込が禁止されていても動作する。

void HarfUART_Class::flush (void)

送信緩衝バッファが空でかつ送信完了になるのを待つ。 全体割込が禁止されていても動作する。

int HarfUART_Class::peek (void)

機能しない。常に -1 を返す。

Print& HarfUART_Class::print (...)

print文とその派生メソッドは<api/Print.h>を参照のこと。

....

この他の、特にタイムアウトを伴うストリーム読込系の機能は用意されていない。 受信動作は殆どの場合、read()よりもreadBytes()のほうが便利かつ合理的だろう。

LINKS

multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)

Clone this wiki locally