宣言
int I2CTR(I2C_TypeDef* I2Cx, uint8_t Addr, uint8_t*Buff, uint8_t TxLen, uint8_t RxLen)
I2Cx
通信に使用するポート
Addr
デバイスアドレスを使用する 7bit形式ではなく8bit形式で渡す
Buff
送受信のバッファを渡す
TxLen
送信データ数を渡す
RxLen
受信データ数を渡す
この関数では送信バッファと受信バッファを兼用している。そのためレジスタアドレスを指定する引数は取らない。レジスタアドレスを指定したい場合はBuff[0]にアドレスを指定し、TxLenを1にする。ROMのようなレジスタアドレスが複数バイトになる場合はBuffに必要なバイト数を設定し、TxLenにその長さを渡す。
送信だけで、受信する必要が無い場合はRxLenを0にすればいい。RxLenが0の場合は送信が終了した段階でStopを発行し関数を終了する。
手持ちのデバイスの中には「レジスタアドレスを指定せずに読みだす」という物がないため、TxLen==0の場合の動作確認はしていない。だけどたぶん失敗すると思う。
const int timeoutは無限ループに入らないようにしている。ただ0x7FFFFFFFでは明らかに長過ぎるから、もっと短い値に変更しないと意味が無い。例を挙げると72MHzで0xFFFFを指定すると67msecほどでタイムアウトする。大雑把な目安としてだいたい1マイクロ秒くらいの分解能になる。例えば10000を指定すると10msecくらいでタイムアウトするので、5000とか10000くらいがいいと思う。
タイムアウトは1回のループ毎に変数をtimeoutで初期化し、whileで比較、デクリメントを行っているだけ。そのためマイコンの動作クロックが変わると待ち時間も変化する。