二線シリアル(I2C) master の読み書き (mwx::periph_wire)
二線シリアル(I2C) master の読み書きを行います。
mwx::periph_wire<MWX_TWOWIRE_RCVBUFF>
はTwoWire
として参照可能です。
以下の定義型で引数や戻り値の型を記載します。
API 中に STOP ビットの扱いが厳格でない呼び出しを行うものもあります。
write(), writer::operator() ()
には、本解説以外にもいくつか引数が定義されてます。
固定配列型
uint8_t cmds[]={11,12};
...
Wire.write(cmds);
initializer_list<>
型
Wire.write({11,12})
ライブラリ内でインスタンスの生成と必要な初期化は行われます。ユーザコードでは Wire.begin()
を呼び出すことで利用可能となります。
requestFrom()
メソッドを用いる場合、データを一時保管するための FIFO キューのサイズを指定できます。コンパイル時にマクロMWX_TWOWIRE_BUFF
に必要なバイト数を指定してコンパイルする。デフォルトは 32 バイトです。
例:
-DMWX_TWOWIRE_BUFF=16
ハードウェアの初期化を行います。
初期化せずにWireの操作を行うとTWELITE無線モジュールがハングアップします。
スリープからの起床時は、スリープ直前で動作していた場合、直前の状態に復帰します。
読み書きの手続きは、以下の2種類あります。いずれかを選択して利用します。
メンバ関数版 (以下のメンバ関数を用いた入出力)
requestFrom(), beginTransmission(), endTransmission(), write()
ヘルパークラス版(stream機能が使用可能)
reader, writer
address
で指定したデバイスが応答するかを確認します。デバイスが存在する場合は true
が戻ります。
本来はバス周波数を変更するための手続きですが、何も処理をしません。
パラメータ
解説
u8mode
バス周波数を指定する。デフォルトは100Khz(WIRE_CONF::WIRE_100KHZ
)
周波数はWIRE_CONF::WIRE_??KHZ
で指定し??
には50
,66
,80
,100
,133
,160
,200
,266
,320
,400
を指定できる。
b_portalt
ハードウェアのピン割り当てを変更する。
ヘルパークラス版はより抽象度が高い実装です。読み書きに対応するオブジェクト reader, writer
を生成することがバスの利用開始となり、オブジェクトを破棄するとバス利用の終了手続きを行います。
if文の判定式内でオブジェクトの生成を行うことで、オブジェクトの有効期間はif節内のスコープに限定され、if節を抜けた時点でオブジェクトは破棄され、その時点でバスの利用終了の手続きを行います。
また読み書きオブジェクトはmwx::stream
インタフェースを実装しているため<<
演算子などを利用することができます。
バスの利用開始と終了をオブジェクトの有効期間と一致させることで、ソースコードの見通しを良くし、また終了手続きの記述漏れなどを防ぐ
mwx::stream
インタフェースによる読み書き手続きの統一
読み込み処理とその終了手続きをスコープ内 if() { ... }
で行うためのヘルパークラスを用いた読み込み方法です。
上記では get_readr()
メソッドにより生成された rdr
オブジェクトを用いて1バイトずつ読み出しします。 メソッドのパラメータには読み込みたい二線シリアル ID を指定します。
if(...)
内で rdr
オブジェクトを生成。(型は、型推論によるユニバーサル参照 auto&&
で解決しています。)
生成した rdr
オブジェクトには operator bool ()
が定義されており、判定式の評価として利用される。指定された ID により通信が可能であれば true
となる。
rdr
オブジェクトには int operator () (void)
演算子が定義されていて、これを呼び出すことで2線シリアルバスから1バイトのデータを読み出す。読み込みに失敗したときは -1
が戻り、成功した場合は読み込んだバイト値が戻る。
if() { ... }
スコープの末尾で rdr
のデストラクタが呼び出され、二線シリアルバスの STOP
を行う。
I2C 読み出しに用いるワーカーオブジェクトを取得します。
書き出し処理とその終了手続きをスコープ内 if() { ... }
で行うためのヘルパークラスを用いた読み込み方法です。
上記では get_writer()
メソッドにより生成された wrt
オブジェクトを用いて1バイトずつ書き出す。 メソッドのパラメータには読み出したい二線シリアル ID を指定します。
if(...)
内で wrt
オブジェクトを生成する。(型名は長くなるため auto で解決)
生成した wrt
オブジェクトには operator bool ()
が定義されており、判定式の評価として利用される。指定された ID により通信が可能であれば true
となる。
wrt
オブジェクトには int operator () (void)
演算子が定義されていて、これを呼び出すことで2線シリアルバスに1バイトのデータを書き出しす。失敗したときは -1
が戻り、成功した場合は書き込んだバイト値が戻る。
if() { ... }
スコープの末尾で wrt
のデストラクタが呼び出され、二線シリアルバスの STOP
を行う。
I2C書き出しに用いるワーカーオブジェクトを取得します。
int
型,uint8_t
型は8bitの転送を行います。
1バイト書き出す。
それぞれのデータ型のサイズ分だけ読み出します。
1バイト読み出します。エラーがある場合は-1を戻し、正常時は読み出したバイト値を戻します。
b_stop
をtrue
にすると、その読み出しにおいてSTOPビットを発行します。
以下の例は、環境センサーパルの温湿度センサーSHTC3の計測例です。
メンバ関数を利用した方法は、抽象度が比較的低く、C言語ライブラリで提供されるような一般的なAPI体系に倣っています。二線シリアルバスの操作手続きがより直感的です。
ただしバスの利用の開始と終了を明示的に意識して記述する必要があります。
指定バイト数分を一括で読み出します。読みだした結果はキューに保存されるため、直後にキューが空になるまで .read()
メソッドを呼び出すようにしてください。
書き出し処理は、beginTransmission()
を実行後、write()
メソッドにより行います。一連の書き出しが終了したら endTranmission()
を呼びます。
書き出しの転送を初期化する。書き出し処理終了後、速やかに endTransmission()
を呼び出す。
1バイトの書き出しを行う。
バイト列の書き出しを行います。
書き出しの終了処理を行います。
パラメータ
解説
u8address
読み出し対象のI2Cアドレス
length
読み出しバイト数
b_send_stop=true
true
の時、読み込み終了時にSTOP
ビットを設定する。
戻り値型 size_type
読み出したバイト数。 0
は読み出しの失敗。
パラメータ
解説
u8address
書き出し対象のI2Cアドレス
パラメータ
解説
value
書き込むバイト
戻り値 size_type
書き込んだバイト数。0
はエラー。
パラメータ
解説
*value
書き込むバイト列
size_type
バイト数
戻り値 size_type
書き込んだバイト数。0はエラー。
パラメータ
解説
sendStop = true
STOPビットを発行します。
戻り値 uint8_t
0: 成功 4: 失敗
パラメータ
解説
addr
読み込み用のI2Cアドレス
read_count
読み出しバイト数(この値を指定すると最後の転送で STOP ビットを発行する)。0を指定した場合は STOP ビットなしとなる(デバイスによっては動作するものもあります)
パラメータ
解説
addr
書き出し用のI2Cアドレス