2023.1.4
前へ
次へ
ホームページトップへ戻る


PIC−USBIO using BASIC

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
USBインターフェースを内蔵したPICを使ってWindowsパソコンで外部回路を制御するための各種I/O基板の製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第146回]



●PICUSBIO−03(95)ICモード(17)スレーブモード(5)送信プログラム

今回は先回とは逆にマスターを受信モード、スレーブを送信モードにしてテストを行ないます。

作成したテストプログラムです。

左側は受信プログラムで右側は送信プログラムです。
左側がマスターで右側がスレーブです。
スレーブ側が送信してそれをマスターが受信します。
マスターの受信プログラムはDS1307受信プログラム([第139回])と基本的には同じプログラムです。
ただ今回はスレーブがDS1307ではなくてPICUSBIO−03です。
PICUSBIO−03はDS1307と比べると応答速度が遅くそのためスレーブ側の送信プログラムはクロックストレッチングを使います。
クロックストレッチングは[第143回]で説明しました。
受信側(マスター)は送信側の準備ができるまで待たされますからDS1307のときのようにBFフラグを見ないで連続して受信を行なうというわけにはいきません。
ですから受信プログラムにはSSPBUFの受信データを読む前にBFフラグ(SSPSTATのbit0)がセットされているかどうかを確認する部分を追加してあります(120、160行)。

C通信では通信の最初にスレーブアドレスとR/Wビットを送ります。
今回のテストでも本来ならばスレーブ側のPICUSBIO−03のスレーブアドレスを設定しなくてはなりません。
今回も先回同様ゼネラルコールアドレスを使うことにしました。
ところがこれはあとで気が付いたことなのですがゼネラルコールアドレスはスレーブアドレスだけではなくR/Wビットも’0’です。
つまりマスター側が送信モードになります。
ゼネラルコールアドレスはICラインに複数のスレーブがつながっている状況でマスターから全スレーブに同時に同じデータを送るための機能と考えられますからR/Wビットは必然的に’0’(マスター送信モード)になります。
全部のスレーブが同時にデータを出力する(マスターが受信モード)などということは考えられませんからそれは当然のことでしょう。
しかし今回はスレーブ側が送信モードですからR/Wビットは’1’になります。
定義からするとそれではゼネラルコールアドレスにはなりません。
それでよいのか?
結果からいいますとおそらくこの場合には’0000000’が通常のスレーブアドレスになるようです。
実際に上記プログラムを実行してみた結果正常に動作することが確認できました。

送信プログラムの説明です。
20行でSSPCON1をクリアします。
繰り返しテストをした場合など前に実行したときのフラグの値などが残っているとプログラムが期待した通りに動かない可能性があるのでそれを避けるためです(SSPENビットをクリアして一旦MSSPモードをOFFにするためです)。
各レジスタについては[第130回]で説明していますので参照してください。
30行のSSPSTATは送信プログラムと同じです。
ここは通常は$80を設定します。
40行でSSPCON1に$26を設定します。
ビット5はSSPEN(SSPモジュールイネーブル)です。
ビット4はCKPビットです。
CKPビットを0にするとSCLラインを強制的に’L’にします(クロックストレッチング)。
CKPビットを1にするとSCLラインを開放します。
ビット3〜0はモード設定です。
’0110’は7ビットスレーブモードです。
[第144回]では40行でCKPビットを’1’にしましたがここではまだCKPビットは’0’にしておくほうがよいことが後でわかりました。
50行でSSPCON2を$81にします。
ここは[第144回]と同じにしました。
SSPCON2はマスターモードとスレーブモードでビットの意味が異なります。
スレーブではビット7を1にするとゼネラルコールアドレスの受信を可能にします。
上に書きましたようにマスター側の設定はR/Wビットが1ですからゼネラルコールアドレスではないことになりますが、SSPADDの値はデフォルトでは’00000000’ですから結果的にゼネラルコールアドレスと同じことになります。
ビット0(SEN)を1にするとクロックストレッチングが可能になります。
60行でBFビット(SSPSTATのbit0)が1になるのを待ちます。
70行でSSPBUFの中身(受信データ)を読んでそれを表示します。
最初の受信はアドレスです。
送信モードではクロックストレッチングを有効にしているときは送信前にCKPビット(SSPCON1のビット4)を’1’にしてSCLラインを開放します(90行、120行)。
マスターからACKが送信されるとMSSPモジュールによってCKPビットは’0’にされSCLラインは強制的に’L’にされます。
95行では次の送信に備えてCKPビットがシステムによってクリアされるのを待ちます。
当初のプログラムではここはBFフラグがクリアされるのを見ていました(100行)。
そのようにすると次のデータを送るときにマスター側でデータが誤って受信されるという問題が発生しました。
BFフラグは8ビットのデータがSSPSRレジスタから送信された時点でクリアされます(ACKの着信前に)。
PICUSBIO用BASICインタプリタのPICOUT命令、PICIN関数は実行に時間がかかります([第129回]参照)。
ACKはBFフラグがクリアされてから遅れて着信することになります([第140回]参照)。
100行のようにBFフラグがクリアされるのを見て次のデータをセットするとMSSPモジュールは遅れて発行されたACKのための9ビット目のクロックをデータ送信のための最初のクロックだと誤認してしまうようです。
その結果ビットがずれたデータがマスターに届いてしまうと考えられます。
それで100行の代わりとして95行を使ったところエラーは起きなくなりました。
CKPビットはSCLクロックの9ビット目の下がりエッジでクリアされますから95行のようにすることでACKのあとで次のデータが送信されることになります。
スレーブ送信モードのCKPビットについては[第143回]に書いています。

今回のテストもできるだけ単純なテストになるように考えてスレーブからの送信データは2バイトだけにしました。
”a”($61)と”b”($62)の2バイトです。

プログラムを実行しました。

先に右側(スレーブ側)をスタート(RUN)させておいてから左側(マスター側)をスタート(RUN)します。
スレーブが送信したデータは無事にマスターに届きました。

PIC−USBIO using BASIC[第146回]
2023.1.4upload

前へ
次へ
ホームページトップへ戻る