PIC−USBIO using BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
USBインターフェースを内蔵したPICを使ってWindowsパソコンで外部回路を制御するための各種I/O基板の製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第144回]
●PICUSBIO−03(93)I2Cモード(15)スレーブモード(3)受信プログラム
前回まででI2Cスレーブ受信モードについてざっと説明しましたので今回は簡単なテストプログラムを作って動作テストをしてみることにします。
I2C通信はクロックSCLとデータSDAとGNDの3本のラインを接続するだけで済むので接続はとても簡単です。
送信も受信も同じ1本のSDAラインを使いますから送受信を同時には行なえません。
送信と受信はモードを分けて別々に行ないます。
マスターモードでの送受信のテストはDS1307と接続して行ないましたがスレーブではそういうわけにはいきません。
SPI通信のときと同じようにPICUSBIO−03を2台使って両者をフラットケーブルで接続してテストを行ないます。
下はその接続図です。
SDAはRB4と端子を共用しています。
SCLはRB6と端子を共用しています。
同じ信号同士を接続しますからフラットケーブルはカットしたりクロスしたりすることなく普通に16pinケーブルをそのまま使って接続します。
下はそのように接続してテストをしている写真です。
右の方に見えているのはCPLDロジアナのケーブルです。
作成したテストプログラムです。
左側は送信プログラムで右側は受信プログラムです。
左側がマスターで右側がスレーブです。
マスター側が送信してそれをスレーブが受信します。
マスターの送信プログラムはDS1307送信プログラム([第135回])と基本的には同じプログラムです。
ただ今回はスレーブがDS1307ではなくてPICUSBIO−03です。
PICUSBIO−03はDS1307と比べると非常に応答速度が遅くそのためスレーブ側の受信プログラムは前回説明したクロックストレッチングを使います。
送信側は受信側の準備ができるまで待たされますからDS1307のときのようにBFフラグを見ないで連続して送信を行なうというわけにはいきません。
ですから送信プログラムにはSSPBUFに送信データを書き込む前にBFフラグ(SSPSTATのbit0)がクリアされているかどうかを確認する部分を追加してあります(70、90、110行)。
できるだけ単純なテストになるように考えて送信データは2バイトだけにしました。
”A”($41)と”B”($42)の2バイトです。
[2023.1.5注記]
このプログラムではエラーが発生する可能性があることがわかりました。
詳しくは[第147回]を参照してください。
I2C通信では通信の最初にスレーブアドレスとR/Wビットを送ります。
今回のテストでも本来ならばスレーブ側のPICUSBIO−03のスレーブアドレスを設定しなくてはなりません。
でもマスターとスレーブをテストのために1対1で接続するためだけにスレーブアドレスを設定するのも面倒な話です。
そこで今回はゼネラルコールアドレスを使うことにしました。
ゼネラルコールアドレスは8ビット全部が0(R/Wビットも0)という特殊なアドレスです。
ゼネラルコールアドレスについては今回の終わりのところで説明をします。
受信プログラムの説明です。
20行でSSPCON1をクリアします。
繰り返しテストをした場合など前に実行したときのフラグの値などが残っているとプログラムが期待した通りに動かない可能性があるのでそれを避けるためです(SSPENビットをクリアして一旦MSSPモードをOFFにするためです)。
各レジスタについては[第130回]で説明していますので参照してください。
30行のSSPSTATは送信プログラムと同じです。
ここは通常は$80を設定します。
40行でSSPCON1に$36を設定します。
ビット5はSSPEN(SSPモジュールイネーブル)です。
ビット4はCKPビットです。
CKPビットを0にするとSCLラインを強制的に’L’にします(クロックストレッチング)。
CKPビットを1にするとSCLラインを開放します。
ビット3〜0はモード設定です。
’0110’は7ビットスレーブモードです。
50行でSSPCON2を$81にします。
SSPCON2はマスターモードとスレーブモードでビットの意味が異なります。
スレーブではビット7を1にするとゼネラルコールアドレスの受信を可能にします。
ビット0(SEN)を1にするとクロックストレッチングが可能になります。
60行でBFビット(SSPSTATのbit0)が1になるのを待ちます。
70行でSSPBUFの中身(受信データ)を読んでそれを表示します。
最初の受信はアドレスです。
受信モードではクロックストレッチングを有効にしているときは1バイトのデータを受信するごとにSCLラインを強制的に’L’にして次のデータが来ないようにマスターを待たせます。
先に受信したデータの処理が終って次の受信ができるようになったらCKPビット(SSPCON1のbit4)を1にしてSCLラインを開放します(80行)。
90行でBFビット(SSPSTATのbit0)が1になるのを待ちます。
100行でSSPBUFの中身(受信データ)を読んでそれを表示します。
110行〜130行で上記をもう一回繰り返します。
150行でSTOPビット(SSPSTATのbit4)が1になるのを待ちます。
本来はSTOPはマスターがいつ発行するかわからないのでデータの受信とからませて毎回ループしながら待つべきですがそうするとプログラムが複雑になってしまうのでここでは単純なテストプログラムとしました。
プログラムを実行しました。
先に右側(スレーブ側)をスタート(RUN)させておいてから左側(マスター側)をスタート(RUN)します。
マスターが送信したデータは無事にスレーブに届きました。
ゼネラルコールアドレスの説明です。
[出典]Microchip Technology Inc. PIC18F13K50/14K50 Data Sheet
I2C通信では通常はマスターがSTARTコンディションの次に送る最初のデータはスレーブを特定するためのスレーブアドレスです。
例外は全てのスレーブに送ることのできるゼネラルコールアドレスです。
このアドレスを使うと理論上は全てのスレーブがACKを返します。
ゼネラルコールアドレスはI2Cプロトコルでリザーブされた特定目的の8ビットアドレスの1つです。
それはR/Wビットを含めて8ビット全てが’0’のアドレスです。
ということはR/W=0ですから送信モード(スレーブでは受信モード)になります。
ま、それはそうでしょう。
ゼネラルコールアドレスはSSPCON2のGCENビットがセットされているときに(スレーブに)認識されます。
STARTビットに続く8ビットがSSPSRにシフト入力されてそのアドレスがSSPADDと比較されます。
同時にゼネラルコールアドレスとも比較されその値はハードウェアに保持されます。
ゼネラルコールアドレスと一致するとSSPSRからSSPBUFに送られて8番目のクロックのときにBFフラグビットがセットされ、9番目のクロックの下がりエッジ(ACKビット)でSSPIF割込みフラグがセットされます。
割込みが許可されていれば割込みプログラムの中でSSPBUFの値を読むことでその値がスレーブデバイスを特定するアドレスなのかゼネラルコールアドレスなのかを知ることができます。
PIC−USBIO using BASIC[第144回]
2023.1.2upload
前へ
次へ
ホームページトップへ戻る