iwanof
それではi2c通信ついて書きます。
i2c通信とは、フィリップス社が提唱しているシリアル・バスで、 2本の信号(SDA,SCL)により複数の機器の間でデータをやり取りをサポートしています。通信速度は標準、ファスト、高速の3タイプがあり、それぞれ100k,400k,3.4M(bit/s)となっています。
i2cにはマスタ、スレーブ、マルチマスタなどのモードがあります。基本的にはマスタからスレーブへ送信や受信の要求を行います。またスレーブにはそれぞれアドレスが設定されておりマスタがスレーブのアドレスを送信することによって決められたスレーブのみと通信することが出来ます。
具体的な通信方法を語ると結構長くなるので、省略します。i2cに関する記事はweb上や文献がたくさん存在するのでそちらを参照ください。
PSoCを使うとi2c通信はとても簡単に実現できます。その例を今から示します。
project name,language,deviceなどはいつも通り選んでください。
<master mode>
まずはマスタモードから説明していきます。'config'の'selection'は'I2CHW'を選んでください。そのあとに出てくるウインドウの'multi usermodule selection'はマルチマスタを選択しました。他のmodeでも実現可能だと思いますが、今回はこのmodeで成功したのでその結果をupします。(他のモードはRAMなどの消費率が低いかも?)
'interconnect'を示します。I2Cmoduleの他にdebug用のLCDをつけました。その以外のmoduleは使ってないので気にしないでください。
次にI2Cの設定です。マルチマスタなのでマスタのアドレスも決められるみたいです。通信速度は400k bit/secです。
デバイスの画像もついでに示します。LCD、I2Cなどの出力ポートが分かりやすく描かれていて大変便利だと思います。
次にマスタのプログラムを示します。I2CHW_1_bWriteBytesという関数でスレーブのアドレス、データ、データのサイズなどを一気に送れます。これは便利な関数でおそらく他のデバイスでこの処理を実現しようとすると、1バイトずつ送らなければならないと思います。そのためプログラムが少し長くなるでしょう。(PSoCでも1バイトずつ送っていると思うが、ここでは1行で記述できるという意味である)その後、送信完了を確認するためI2Cのマスタのstatusがwrite_compliteになるかチェックしています。(status/control registerの6bit目を読んでいるらしい)無事送信が完了したら、マスタのstatusをクリアして次の動作に移ります。
送信が終わった後は、スレーブからデータを読み込んでいます。受信にはI2CHW_1_fReadBytesという関数を使っています。これも上記と同じ理由で大変便利です。そして受信したデータをLCDに表示しています。
<slave mode>
'selection'では'I2CHW','PWM','LCD'を最低限選びましょう。スレーブではマスタから送られてきたデータに従ってサーボモータの回転角度を制御するためPWMを使います。のでPWMの設定もしておきましょう。(PWMの記事を参考にしてください)スレーブのアドレスは100にしています。LCDは送られてきたデータの表示、PWMに書き込む値を表示するために使っています。
プログラムを示します。いらないことも書いてありますが気にしないでください。バッファの定義、I2C、PWM、LCDのスタートなどは確実に行ってください。
プログラムではマスタがwriteが成功したかを確認してデータ読み込みます。その後いろいろやってるのは遊び心です。基本的には定型文、受信したデータ、pwmに書き込むデータなどを表示しています。LCD_PrStringは配列の先頭ポインタを読み込み順次更新して表示してくれるので大変楽です。(変数みたく入れているけどホントは配列です)その後PWM16_1_WritePulseWidthという関数でパルスの幅を変更しています。ちなみにPWMのperiodも設定できます(周期を変えられる)このまま書き込んではモータの回転速度が幅の変化に追いつかないのでウェイトをかけています。
プログラムの後半はスレーブからマスタへのデータの送信です。おそらくバッファのポインタを更新してマスタ側がデータを読んでいるのだと思います。
それでは実行結果を示します。
マスタ側のLCDの様子です。スレーブ送信要求によって送った文字がLCDしっかり表示されているのが分かります。
スレーブ側のLCD表示です。上の段右側にPWMに書き込むデータがASCIIで表示してあります。実際にはそのまま書き込んだら値が大きすぎるため補正する必要があり、補正した結果が上の段の左の2桁(1バイト)数字です。
この場合'h'のASCIIキャラクタである0x68から0x57を引いた0x11をPWMの'on'の時間にしているということです。
下の画像は受信完了した図です。
実験風景などをチラッと。
モータは2台同時に違うデータを書き込んでみました。
その動画です。
いつも通り不備があります。まず画像が見えない。文章が不可解、PWMの設定が結構いい加減などです。近いうちしっかり書きたいと思います。次はシリアル通信でスレーブアドレス、データを取得し、スレーブに書き込む、AD変換を使う(i2cとあわせて)などをやるつもりです。
ご意見、ご感想、特に多いと思われるご指摘などをお願いします。手紙、または電子メールで。