N.Yamazaki's blog

主に音声合成について思ったことを書いてみようと思います。
<< 音声合成LSI用のオーディオアンプ(再考) | main | 簡単!ATmega328Pにブートローダを書きこむ(第2弾) >>
ArduinoのWireライブラリはI2Cのリピーテッド・スタートが使えます
ArduinoのWireライブラリは、読み出しの際のリピート・スタート・コンディションが使えないって書いてあるサイトが多くありますが、今は使えるようになってます。

通常、I2Cデバイスにデータを書き込むときは単にwrite()を連続すれば良いのですが、I2Cデバイスからデータを取得するときは、読み込むレジスタのアドレスを指定(Write)してから、データを読み込む2段階の処理となります。
以下は、I2Cデバイスにレジスタのアドレス(1byte)を指定した後、2byteのデータを読み込むありふれたコードです。

  Wire.beginTransmission(DEVICE_I2C_ADDRESS);
  Wire.write((byte)REG_ADDR);
  Wire.endTransmission();

  Wire.requestFrom(DEVICE_I2C_ADDRESS, 2);
  uint16_t val = Wire.read();
  val = (val << 8) | Wire.read();


このコードでは、beginTransmission()からendTransmission()までの通信と、その後のread()はそれぞれ独立した通信です。具体的には、endTransmission()でストップビットが発生し、一旦バスが開放されます。

問題は、I2Cデバイスの中には、データ取得の際にレジスタのアドレス指定とデータの読み込みを1つの通信、すなわちリピーテッド・スタート・コンディションを用いて行うように指定しているものがあります。
そこで、これをArduinoのWireライブラリを使って書くと以下のようになります。
 

  Wire.beginTransmission(DEVICE_I2C_ADDRESS);
  Wire.write((byte)REG_ADDR);
  Wire.endTransmission(false);    // Stopしないで継続

  Wire.requestFrom(DEVICE_I2C_ADDRESS, 2, false);     // まだ、Stopしないで継続
  uint16_t val = Wire.read();
  val = (val << 8) | Wire.read();
  Wire.endTransmission(true); // ここでStop


endTransmission()、requestFrom()に引数を追加しているのがミソです。
これにより、ストップビットを出さずに、Write()/Read()を繰り返すことができます。
requestFrom()の最後の引数をtrueにして、最後のendTransmission()を省略してもよいかもしれません(未確認)。
ちなみに、これらの引数はWireライブラリのマニュアルにちゃんと書いてありました。
 
| その他 | 15:49 | - | - |
PROFILE
Follow
CATEGORIES
LATEST ENTRIES
SEARCH THIS SITE
RECOMMEND
RECOMMEND
RECOMMEND
Arduino Uno
Arduino Uno (JUGEMレビュー »)

AquesTalk pico LSIの評価ボードとして最適
RECOMMEND
Raspberry Pi Model B+ (Plus)
Raspberry Pi Model B+ (Plus) (JUGEMレビュー »)

これと AquesTalk pi で簡単にテキスト音声合成!
RECOMMEND
RECOMMEND
RECOMMEND
SONY MDR-CD900ST
SONY MDR-CD900ST (JUGEMレビュー »)

普段これで開発しています。
RECOMMEND
RECOMMEND
RECOMMEND