PIC−USBIO using BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
USBインターフェースを内蔵したPICを使ってWindowsパソコンで外部回路を制御するための各種I/O基板の製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第141回]
●PICUSBIO−03(90)I2Cモード(12)マスターモード(11)DS1307受信プログラム(5)
前回からの続きです。
うっかりひきずられてしまった「先入観」とは。
最後のデータの受信後にPIC(マスター側)が送出するSDAラインのACK、NACKの状態(’L’または’H’のレベル)はSTOPコンディションになるまでずっと続いてPICから出力されていると思い込んでしまったことです。
その間にDS1307から何かが出力されるなどとは思いませんでした。
ここはもっとよく考えてみるべきでありました。
よくよく考えてみればACK、NACKの送出後はSDAラインは開放されているのではないかと考えられたはずでした。
そうでなければスレーブは次のデータを送信することができません。
そのように考えればもっと早く答えに行き着いたはずでした。
しかしこのときはSDAラインはACK送出のあともマスターが制御していると思い込んでしまっていたので答えに行き着くまでに無駄な時間を費やしてしまいました。
無駄な時間を費やしたあとでやっと考えが間違っているのではないかと思い始めました。
ひょっとすると最後のACKのあとSDAラインが’L’になってしまうのはPIC(マスター)ではなくてDS1307(スレーブ)から’L’が出力されているからではないか?
そう考えると最後のデータのあとにはNACKを送らなければならないというDS1307のData Sheetの記述にはそれなりの理由があるように思えてきます。
これはPICの側の問題というよりもDS1307の側の問題ではあるまいか?
そこで試しに異常な状態が発生したあとコマンドプロンプトのBASICシステムは起動した状態のまま、そしてパソコンとPICUSBIO−03はUSB接続をしたままでPICUSBIO−03とDS1307をつないでいる16pinケーブルをPIC側のコネクタから外して少しの間DS1307の電源ラインをOFFにしてみました。
そのようにしたあとでもう一度ケーブルを接続しました。
DS1307から何らかの信号が出力されていると仮定して、それならば一旦DS1307の電源をOFFにすればDS1307がリセットされるのではないかと考えたからです。
そのようにしたあと、問題の受信プログラムを実行したところ、エラーは発生せずに正しく受信が行なわれました。
問題はPICの側ではなくてDS1307の側にあったのでした。
ACKを出力したあとPICの側はSDAラインを開放していたのでした。
それを「強制的に」’L’にしていたのはDS1307だったのでした。
そうだとすると。
ACKを受信したあとクロックも出ていないのにDS1307はどういうタイミングで’L’を出力しているのだろうか?
そこが気になりました。
CPLDロジアナの波形を確認してみるとACKが出力されたあと’H’(つまりハイインピーダンス)になることなく、ACKの直後から’L’になっているように見えます。
これではDS1307は最後のクロック(9番目のクロック)が終った直後から’L’を出力しているようにしか思えません。
???
あ、あ、あ!
わかった!
そういうことだったのか!
やっと全てが理解できました。
なんともおばかな話でありました。
当たり前のことだったのです。
マスターの側は最後のデータを受信したのでそこでACKを送ってそのあとSTOPコンディションに入ろうとしていてもそれはDS1307にはわかるはずのない話です。
データを送ったあとACKがきたらDS1307はどうするか?
次のデータを送信しようとします。
そのタイミングは?
おそらく9番目のクロックの下がりエッジで次のデータのbit7を出力することになるのでは?
そしてたまたまそのbit7が’0’だったなら。
そういうことだったのでした。
もっともその場合bit7が’1’でも結果は同じことです。
マスターはSTOPコンディションを送ったつもりでもスレーブ(DS1307)はデータ送信を続けようとしますからこの時点でマスターとスレーブは完全に食い違ってしまいます。
それではまともに通信が行なわれるはずはありません。
唯一の解決策はDS1307をリセットすることだったのでした。
やっとDS1307のData Sheetに最後のデータ受信のときにはACKではなくてNACKを送ると書いてある意味が理解できました。
DS1307の場合、データ送信の終わりを知るためにはNACKを受信する必要があったのでした。
しかし。
それはDS1307固有のルールなのか?
この時点では私はそのように考えていました。
PIC18F13K50のData Sheetを何回か読み直してみたのですがそんなことはどこにも書いていなかったからです(そのように思ったのも私の思い違いでした)。
その疑問は後になってから解けました。
次回から書く予定のスレーブモードのところに書いてありました!
順序として先にマスターモードからテストをしようと思ったためスレーブモードについての説明文は読み飛ばしていました。
PIC18F13K50のData Sheetではスレーブモードの説明が先にあります。
先にスレーブモードについて理解するべきなのでそういう順序で説明がなされているのかもしれません。
先にスレーブモードについての説明文をしっかり読めば無駄な時間を費やすことはなかったでありましょう。
やっぱり説明文は飛ばし読みなどしないで順序通りにしっかり読まなければいけません。
年の終わりの反省でありました。
PIC−USBIO using BASIC[第141回]
2022.12.30upload
前へ
次へ
ホームページトップへ戻る