« PSoCマイコンのユーザーモジュールの日本語データシートがあるではないか!! | トップページ | Arduino初体験 »

2010年10月31日 (日)

I2C通信について

I2C通信をしたくて調べて、いろいろ少しづつ分かってきたのですが、まだわからないところがあります。
だれか教えてください。お願いします。

まず、Arduinoでのことなのですが、Wireライブラリを使ってマスタの場合です。
Wire.recuestFrom(address,quantity);関数のことなのですが、
ここでいう要求するってどういうことでしょうか?

というのは、マスタはまず最初にスレーブのアドレス(7bit)を送信して、R/Wを送信しますよね。
R/Wのところを1にしてやると、ACKの後にスレーブからデータが来ますよね。
そのあとに何バイト受信したらACKを出さないで停止条件を出すんですよね。
要求するとはこのことなのですか?
パラメータのquantitiyつまり要求するデータのバイト数っていうのは、(マスタが)ACKを出さないようにするまでのバイト数を示すのですか?
つまり、「何バイト欲しい」っていうのをスレーブに伝えるのではなく、何バイトか受信したら強制的に終了するためのバイト数なのですか?

下はI2Cの仕様書です↓(クリックすると拡大します)

I2c3_2

もう1つ疑問があります。
PSoCでのI2CHWのAPI関数についてなのですが、(スレーブに設定した場合)

①マスターからスレーブ(ここでいうPSoC)への書き込み
PSoCにとっては読み込みなのに関数がWriteって書いてあるそうなのです(ややこしい)。
PSoCがマスタからの信号を自動的に読み取って、I2CHW_1_bReadI2CStatus();がI2CHW_WR_COMPLETEに変化する
→I2CHW_1_ClrWrStatus();する
→I2CHW_1_InitWrite(バッファ名,バッファサイズ);で「バッファ名」にマスタから受け取った信号が入る
→「バッファ名」を読み取ったらOK!
 という流れで合っていますか?

②スレーブ(ここでいうPSoC)からマスタへの読み込み
PSoCにとっては書き込みなのに関数がreadって書いてあるそうなのです。
例えばbuf_rdという変数をつくる
→I2CHW_1_InitRamRead(buf_rd, バッファサイズ);でRAMに移しておく
→マスタから送信を要求されたら自動的にRAMに入っているのを送信する
→I2CHW_1_bReadI2CStatus();がI2CHW_RD_COMPLETEになる
という流れで合っていますか?

どなたか知っている方、コメントしていただけたら幸いです。

« PSoCマイコンのユーザーモジュールの日本語データシートがあるではないか!! | トップページ | Arduino初体験 »

ロボットのソフトウェア」カテゴリの記事

コメント

Arduinoのwire.requestFromについては,だいたいそのような理解であっています。requestですから,マスタがスレーブに対して,○バイトくれ!と命令している感じでしょうか。ただ,○バイトの部分はスレーブに送られるのではなく,ArduinoのwireライブラリのrequestFrom関数の実装の中で使われているはずです(必要なバイト数で終了する)。だから,requestFrom の後に,マスタ側でwire.receiveで必要なバイト数読む必要があります。ArduinoでコンパスHMC6352を使っているスケッチ例などを見るとわかりやすいと思います。
ReadとWriteですが,I2Cは対等な通信ではなく,master(ご主人様)とslave(従属者)の関係ですから,用語がマスタ側からみたようになっているんじゃないでしょうか。
PSoCの方ですが,I2CHWモジュールは,データの受信,送信は自動で行われます。バッファを(例えば配列で)用意しておいたら,受信はその配列に自動で順次格納されていくし,送信はその配列のデータを自動で送信します(要求があれば)。
で,そのバッファのデータの送受信がなされる位置(ポインタ)があって,送受信に伴って変化(インクリメント)していくので,送受信が終わったらI2CHW_1_InitWriteやInitRamReadなどの関数でポインタを最初に戻しておくのだと思います。(次にバッファを最初から読んだり書いたりするように)
受信データは,単純にバッファにした変数の中身を読めばOKです(例えば,var = buffer[2];とか)。送信の時は,バッファ変数に送りたいデータを入れておけばOKです。
ここ↓なんか,参考になるかと思います。
http://shokai.org/blog/archives/5230

早速返信していただいて、とても分かりやすい説明をありがとうございます。
なるほど。ポインタがいちいちずれるんですね。
てっきり変数をRAMに代入するのかなと今まで思っていました。
RAMには変数のアドレスが載っていて、PSoCはRAMに載っている変数を参照して動作するということであっていますか?これがポインタだということですか?
だから、橋本商会さんのスレーブ用プログラムは送受信したあとに初期化しているのですね。
やっとどういうことかが分かってきました。

ちなみに橋本商会さんの記事を見て、ポインタの初期化の意味が分からなくてこの記事を書きました(笑)

ありがとうございました。

wire.requestFromに関してですが,そういえば,TJ3のI2C通信では,スレーブに「○バイト送るよ」とか「○バイトちょうだい」という○バイトの部分もアドレスに続けて送っていたように思います。D_TJ3.cのI2Cinterruptの部分を見てみて下さい。メインルーチンではバッファ配列に送受信データ入れておいて,割り込みの中でI2C送受信の処理をしているので,PSoCでの通信にも参考になるかもしれません。もし処理しやすいようにしたいなら,Arduinoでも自分で○バイトの部分を先に送ればいいだけですので。
参考まで。

そんなふうになっているのですね。
ありがとうございます。

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1389908/37471527

この記事へのトラックバック一覧です: I2C通信について:

« PSoCマイコンのユーザーモジュールの日本語データシートがあるではないか!! | トップページ | Arduino初体験 »