shokai14ビットのADコンバータ1つと、AMUX4(4チャンネルアナログマルチプレクサ)を組み合わせると複数のピンからAD変換が使える。Designer5.0では1つしか配置できなくて困った。考えたらマルチプレクサ使う方が自然だな。右上のADC以外は関係ないPGAの設定1.0倍で、AMUXがあるアナログマルチプレクサ1に接続する。Inputのソースは一応指定するが、GainをDisconnectedにすると使わないようにできる。Viewには表示されないけど、配置はされてる。アナログマルチプレクサ1として設定する。AMUX4の他にも8もあるので、まあたくさん増やせる。UARTのTX8で、14bitADCINCの値を送る。}}AMUX4を切り替えた直後にAD変換を開始するのがなんとなく嫌だった(物理的に回路が切り替わっているわけだし)ので、一瞬waitを入れてからAD変換するようにした。CY8C29466のI2Cモジュールを試した。I2Cは2本の信号線の上にmaster/slaveの2種類のノードを合計100個以上載せて相互に通信できるプロトコル。動作速度が違う部品同士をより少ない結線数で相互接続させる事を目的として、1992年にPhilipsが作って2004年に特許が切れている。今ではほとんどのマイコンにI2C通信をするモジュールがついているし、外部メモリやセンサーなどもI2Cで値を返す物がある。linuxのkernelにも入っていて(/usr/include/linux/i2c.hとか)マザーボード上の温度センサとかに使われているらしい。このへんに詳しく書いてある。Semiconductor特に仕様書pdfはちゃんと読んでみたらかなり勉強になったのでオススメ。Datasheetのp.39,40ものを参考にした。5.0+SP6で作ったプロジェクトまるごとgithubに置いた。git://github.com/shokai/i2c-uart-cy8c29466.gitで取得できる。3つ並んでいるPSoCマイコンのうち一番下がmasterで、上2つがslaveデバイス。I2Cの接続構成とプルアップ抵抗に適切なプルアップ抵抗の計算方法が書かれている。電源5Vで100kbpsか400kbpsなら2kΩ〜5kΩが最適値とのこと。masterに付いているボタンを押すと、2つのslaveにLED点灯命令を送る。ボタンを離すと消灯する。slave側のボタンは、それぞれmasterの2つのLEDの点灯/消灯に対応している。masterはslaveをコントロールするだけでなく、I2Cとシリアル通信のブリッジになっている。slaveからのデータをslaveのアドレス名と共にUARTでパソコンに中継する。パソコンからmasterマイコンに’U’か’D’の文字を送る事と、masterは全slaveにLED点灯/消灯を送る。UARTとRS232Cのレベル変換にはADM3202を使った。だいたいそういう内容のビデオ■デバイス設定master側。パソコンとのシリアル通信で9600bpsを作るためにVC1,VC3を設定している。動作電圧やCPUクロックなどはデフォルト値。masterモードでモジュールを置いた。100kbpsでPORT1の5番と7番ピンをI2Cに使う。bufferはプログラム中で自分で用意したBYTE配列を使ってもらうように設定。シリアル通信で9600bpsが出るようにUARTモジュールを設定。CY8C29466でUART受信割り込みでくわしく書いた。3つのLEDに使うピンは出力をStrongにして3V出るようにした。タクトスイッチにつなぐPort2の2番ピンは両エッジ入力割り込みを設定しつつ内部でプルアップして、ブレッドボード上でも100Ωの抵抗でプルダウンする。するとチャタリングが起きない。配置図アナログブロックは使っていないので上の方だけ。UARTがPort2の4,5番ピンから出るように引き出した。Resourceは初期値のままI2CHWモジュールををslaveで置いた。速度はmasterに合わせる。slaveデバイスのアドレスは7bitだが、0x00~0x10までの16個のアドレスはプロトコルに予約されているので、0x11からの112個が使える。今回はmasterのプログラムで0x11~0x20のデバイスがいるか確認しながら動作するようにしているので、アドレス17~32のどれかを使えばいい。masterと同じ様にLEDとタクトスイッチ用のピンを設定。なにも結線していない■プログラムmaster側slaveアドレス0x11から0x20までのデバイスに、順にTXバッファを書き込み、RXバッファに読み込む。送受信を待っている間、timeout_countをカウントアップし続けて、閾値以上になるとタイムアウトするようにしている。これで存在するかわからないslaveとやりとりできるし、動作中にslaveデバイスが増えても問題なくネットワークに参加させられる。CY8C29466でUART受信割り込みで書いた)のだが、I2Cはメインループの中で処理している。I/OからのイベントでUARTぐらいなら使ってもいいけど、16個のslaveとのやりとりを割り込みの中でやると多重割り込みが起こりやすいので、各ルーチンからbufferを読み書きしてそれを定期的にslaveと共有するという方式にした。Timerモジュールで定期的に回すようにすると良いと思う。}}slave側slaveもmasterと同じ様にglobalにバッファを用意して、そこに適当に現在の状態を読み書きし、定期的にメインループ内でmasterと通信し共有している。この方が素直に書きやすい。LEDとボタンの状態を結びつける情報を1byte目に置いているが、それ以外の情報をやりとりする場合もシリアライズとかして通信するのではなく2byte目以降を使う方がいい。必要な変数を定期的に同期させられる、分散オブジェクト風に書いた方がすっきりする(PSoCのstring.hがおかしいという理由もあるけど)あと、ややこしいのがslaveなのでI2CHW_1_InitWrite関数を呼ぶとmasterからslaveへの書き込みが起こる。