-
Notifications
You must be signed in to change notification settings - Fork 0
SoftwareUART
最小フットプリントの、二線式半二重UART通信SoftwareUART_Class
基本クラス。
Arduino互換APIの<SoftwareSerial.h>
を代替するが上位互換ではない。
プロトコルは 8N1 専用。
割込も計時器周辺機能もFIFOバッファも使用しない。
従って全体割り込み禁止中でも、割込ハンドラの中からでも使用できる。
実装サイズは(print
拡張を使わなければ)必要最小限しかない。
reduceAVR は未対応
#include <variant.h> /* 外部端子定義取得 */
#include <SoftwareUART.h>
SoftwareUART_Class SoftSerial = {PIN_USART0_TXD, PIN_USART0_RXD};
void setup (void) {
SoftSerial.begin(CONSOLE_BAUD);
}
void loop (void) {
size_t length;
char buff[INTERNAL_SRAM_SIZE / 4]; // 適当な大きさの1行ぶんのバッファメモリ
length = SoftSerial.readBytes(&buff, sizeof(buff), '\n'); // `\n` 受信で方向切替
if (length) SoftSerial.write(&buff, length);
}
このクラスは半二重通信専用なので、送信と受信は同時には行えない。
また受信に際してはreadBytes
メソッドだけが実装されている。
このreadBytes
実行中のみ外部端子を監視し、変化があれば受信キャラクタとして認識しようとする。
その性質から「固定長ヘッダ+可変長ペイロード」形式の受信用途には適していない。
1. 計時基準は遅延ループで生成されるため、受信送信とも動作中は全体割込が禁止される。
ソフトウェア模倣動作なので対応可能なボーレートはF_CPU
に強く依存する。
115200
bps で送受信できるようにするには、少なくとも12000000L
(12MHz)以上必要だろう。
2. 通常の UART通信クラスと異なり、以下はのメソッドは存在せず、使用できない。
-
read
available
availableForWrite
peek
3. 以下のメソッドは存在するが、何もしない。
flush
依存性:<avr/io.h>
<util/atomic.h>
<api/delay_busywait.h>
<api/Print.h>
クラスインスタンスを作成するには、送信端子と受信端子を初期値として指定する。
指定できるのは<variant.h>
で定義されているPIN_Pxn
とその別名である。
送信専用あるいは受信専用とする場合は、使用しない方にNOT_A_PIN
を与える。
UARTの使用を、任意のボーレート値で開始する。 自身のオブジェクトを返すので、メソッドチェーンを後続できる。 指定するボーレート値は変数ではなく、静定数であるべきだ。
SoftwareUART_Class SoftSerial = {PIN_PA2, PIN_PA3}; /* クラスインスタンス */
SoftSerial.begin(CONSOLE_BAUD);
begin
の別版。
受信専用UARTの使用を、任意のボーレート値で開始する。
自身のオブジェクトを返すので、メソッドチェーンを後続できる。
指定するボーレート値は変数ではなく、静定数であるべきだ。
受信専用であるからwrite
print
等の送信メソッドを使用してはならない。
SoftwareUART_Class SoftSerial = {NOT_A_PIN, PIN_PA3}; /* クラスインスタンス */
SoftSerial.beginRxDriveOnly(CONSOLE_BAUD);
begin
の別版。
送信専用UARTの使用を、任意のボーレート値で開始する。
自身のオブジェクトを返すので、メソッドチェーンを後続できる。
指定するボーレート値は変数ではなく、静定数であるべきだ。
送信専用であるからreadBytes
受信メソッドを使用してはならない。
SoftwareUART_Class SoftSerial = {PIN_PA2, NOT_A_PIN}; /* クラスインスタンス */
SoftSerial.beginTxDriveOnly(CONSOLE_BAUD);
UART通信の使用を停止し、専有していた外部端子を未使用に戻す。
通信を再開するには先立って再びbegin
を実行する。
- 一般に、UART対向機器の電源が落ちている場合は TX線が Hi-Zか LOWになるだろう。
これを調べるには TX端子をデジタル入力許可に変えなければならない。
end
後はそれが可能な状態になる。
1キャラクタを出力する。 出力中は全体割込が禁止される。 常に1を返す。 全体割込が禁止されていても動作する。
指定のバッファから指定の量を書き出す。書けた量を返す。 全体割込が禁止されていても動作する。
指定の_buffer
に、最大_limit
文字数、
あるいは_terminate
指定キャラクタ出現までを取得する。取得されたキャラクタ数を返す。
_buffer
の最後に\0
は補完されないことに注意。
_terminate
指定キャラクタは取得内容に含まれる。しかし\0
は指定できない。
受信キャラクタが\0
であればそれは含まれる。
そしてBREAK と見做して受信待機を打ち切るだろう。
このメソッドが呼ばれると、少なくとも 20bit時間のあいだ通信線を監視して
IDLE 状態が続いたなら何も取得せずに終了し0
を返す。
STOP ビット以外の受信中は全体割込が禁止される。
つまりNOBLOCK動作であるから、必要に応じて繰り返し呼び出さなければならない。
逆に_buffer
に格納される最初の文字はその前に 約10bit長以上の IDLE 状態が検出されなければならない。
従って例えば シリアルGPSの NMEA出力は、概ね新たな行頭から採取されるだろう。
_swevent
が0
以外であるなら、それは事象システム EVSYS ストローブ指令と解釈され、
最初の受信キャラクタ検出の瞬間に以下の IOレジスタへ代入し、
任意の事象イベントを発火することが出来る。
tinyAVR-0/1 | megaAVR-0 | その他のmodernAVR |
---|---|---|
EVSYS_ASYNCSTROBE | EVSYS_STROBE | EVSYS_SWEVENTA |
各ビットが
EVSYS
チャネル番号[0-7]に対応。チャネル8番以上には対応していない。
発火イベントが割込を惹起する場合はそちらの実行が優先され、そして受信落ちを経験するだろう。 だが全体割込禁止中でもこのメソッドが機能することは留意されたい。
この機能は例えば 1PPS割込のない シリアルGPSで、秒タイミングを測るのに使える。
現在の基準遅延ループ数を返す。デバッグ用途で通常の用途はない。
print文とその派生メソッドは<api/Print.h>
を参照のこと。
....
この他の、特にタイムアウトを伴うストリーム読込系の機能は用意されていない。
Twitter(X): @askn37
BlueSky Social: @multix.jp
GitHub: https://github.com/askn37/
Product: https://askn37.github.io/
Copyright (c) 2022,2023 askn (K.Sato) multix.jp
Released under the MIT license
https://opensource.org/licenses/mit-license.php
https://www.oshwa.org/
multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)