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


PICBASICコンパイラ

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
まるでインタプリタ。でもコンパイラです。超カンタン超シンプルです。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第106回]



●SDカードIF(26)ND80Z3.5に接続(19)解決編(4)

前回からの続きです。
前回までのところを読んでいただいても「なんのこっちゃ?」「どこが解決編やねん」とすっきりしないお気持ちかもしれません。
私自身は全てわかって納得しているのですが、それをうまく書いて説明することができません。
でも。
前回をお読みいただいたあとで今回をお読みいただければおそらくご理解いただけるのではと思います。
今回が本当の解決編かと。
下は少し前(10日ほど前)に動作テストをしたときのログです。
logfile nd80zlog\11141215.txt open

ND80ZVに接続しました
0001 0000 - z
1000 00C3 - 
*** nd80z3 basic ****
ndwr2h.bin loaded,from E23F to E535
>jp a000

)i
13
E:92
)i
13
00
)ro test24.bin
04
00
00
0006
)rb
05
00
)e
>in 82
3D
>jp a000

)i
13
00

電源をONにしてND80Z3.5を立ち上げて最初に実行したJP A000です。
PIC18F2550にアクセスするプログラムはND80Z3.5のアドレスA000にロード済みです。
ボタン電池でバックアップされていますからZB3BASICを起動したあとすぐに実行できます。
最初のIコマンドで表示されるE:92については[第102回]でプログラムを修正して表示しないようにしたのですが、このログは修正前ですのでE:92が表示されています。
このところ書いております”FF”問題とは関係ありませんからここは無視してください。
Iコマンドをもう一度実行すると00が表示されます。
続いてROコマンドでTEST24.BINファイルをオープンします。
RBコマンドで1バイトをREADして最初のDATA”00”がPIC18F2550から送出されそれが表示されました。
RBコマンドの次の”05”はPIC18F2550からのエコー(RBコマンドのコード)でデータではありません。
PIC18F2550からの送信データはその次の”00”です。
その後Eコマンドでプログラムを終了しました。
次にZB3BASICのマシン語コマンドIN 82を実行しその結果”3D”が表示されました。
この値が解決編として重要な意味を持っています。
それについては後ほど説明をします。
ここまで実行したあと、もう一度JP A000を実行しました。
そしてIコマンドを実行しました。
”FF”問題について最初に書いたのは[第99回]でした。
そこではRBコマンドを実行したあと一旦プログラムを終了してから再度JP A000でプログラムを実行してそこでIコマンドを実行するとPIC18F2550からのエコーが正しく表示されず”FF”になってしまいましたと書いています。
上のログのプログラムは修正前のプログラムで[第99回]のプログラムと基本的には同じものです。
[第99回]ではJP A000でプログラムに再エントリした後でIコマンドを実行すると”FF”が表示されてしまったのですが、今回のログではそのようなエラーは発生していません。
当初はなぜエラーになるのかがはっきりわかっていなかったのですが今はその原因はわかっています。
プログラムをどこで終るかによって次に再実行したときにエラーになったりならなかったりします。
それがわかりましたからエラーを再現することもまたエラーを発生させないようにすることもできます。
上のログではエラーは発生していませんが下のログでは[第99回]と同じエラーが発生しています。
)ro test24.bin
04
00
00
0006
)rb
05
00
)rb
05
90
)e
>in 82
7D
>jp a000

)i
FF
E:82
)

先ほどのログと同じようにEコマンドでプログラムを終了した後でIN 82を実行しています。
その結果、先ほどのログでは”3D”が表示されましたが今回は”7D”が表示されています。
IN 82を実行したときに”7D”が表示されていると次にJP A000を実行し、続いてIコマンドを実行すると”FF”エラーが発生し、”3D”が表示されたときはエラーは発生しません。
もっと正確に言うとIN 82で表示される値がビット表現で01XX XXXXのときにエラーになり00XX XXXXのときにはエラーになりません。
IN 82は82C55のCポートの入力値を読む命令です。
Cポートのビット7(PC7)にはPIC18F2550のRA3の出力が接続されていてビット6(PC6)にはRA2が接続されています。
Eコマンドでプログラムを終了したときにPIC18F2550のRA3の出力が”0”でRA2の出力が”1”のときにエラーが発生し、RA3の出力が”0”でRA2の出力も”0”のときにはエラーになりません。
RA3はREADY_/BUSY出力で通常はPIC18F2550は受信待ちになりますからRA3=0でスタンバイしています。
RA2はデータ出力で次に何かを出力するまで最後に出力したときのままになっています。
そこが”1”だとエラーが発生するということがわかりました。
前回の検証でPIC18F2550がRESETから開放されてプログラムが起動されてTRISA命令が実行されたときにRA3=0、RA2=1だとそれ以後ND80Z3.5とPIC18F2550との交信のタイミングが食い違ってしまう可能性があることがわかりました(前回参照)。

確かに先ほどのログと上のログを見るとIN 82の実行結果とその次にJP A000を実行してIコマンドを実行したときにエラーが発生するかしないかいうことがぴったり符合しています。
そこまではわかりました。
すると次にはどういうときにIN 82の値が”3D”になり、またどういうときにその値が”7D”になるのかを解明しなければなりません。
それは言い換えると、上に書きましたように通常はプログラムの終了時にはRA3=0になっていると考えられますから、プログラムの終了時にRA2が”0”になっているのはどういうときで、”1”で終っているのはどういうときなのかを明らかにすることだと言えます。
RA2はPIC18F2550のシリアルデータ出力ラインです。
PIC18F2550が8ビットのデータを出力(送信)するときにはそれをシリアルデータに変換してRA2から送出します。
RA2から出力されるシリアルデータはビット0から始まってビット7で終ります([第99回]参照)。
ビット7まで送出したあとRA2の出力は次にデータを送出するまでの間最後に送出したビット7の値を維持しています。
つまりプログラムを終了したときにPIC18F2550から最後に送出したデータのビット7が”1”のときにRA2=1になります。
送出したデータのビット7が”0”のときにRA2=0になります。
先ほどのログでEコマンドで終了したときの直前のPIC18F2550からのデータはRBコマンドの実行によって送出された”00”(0000 0000)でしたからビット7は”0”です。
このときはエラーにはなりません。
後のログでは”90”(1001 0000)が送出されて終りましたからビット7は”1”です。
このとき次にJP A000を実行したあとでIコマンドを実行すると”FF”エラーが発生します。

JP A000を実行すると最初にPIC18F2550をリセットします。
私はPIC18F2550はリセットするとI/Oポートの出力ラッチはクリアされて0になると思い込んでしまっていました。
PIC18F2550は(それに限らずおそらく多くのPICは)リセットによってI/Oポートの向きが入力になります。
それだけではなくてアナログと兼用しているポートはアナログモードになります。
そしてアナログモードになっている端子をデジタル的に読むとその値は”0”になります。
ということから「なんとなく」リセットによってI/Oポートの出力は0クリアされると思い込んでしまったようです。
思い込みは危険であります。
やっぱり何でもしっかり確認すべきでありました。
ということで前回Data Sheetを確認した結果PIC18F2550の出力ラッチ(LATA)はリセット(MCLR RESET)によっては変化しないということが確認できました。

そこまでわかってしまえばエラー回避のための対策はおのずから明らかになります。
PIC18F2550についてはみっともないプログラムになっていましたのでTRISAよりも前にLATAの値をFFにするように変更しました。
TRISで向きを出力にしても82C55のように出力ラッチがクリアされたりしませんから、そのようにするとリセット後からずっとRA3、RA2のラインはHになります。
おそらくはそのようにプログラムを変更しただけでエラーは回避されると思いますがさらに念のためにND80Z3.5側のプログラムはPIC18F2550のリセットを終了したあと十分な時間を置いてからPC7(RA3)=0、PC6(RA2)=1を確認するように修正をしました。

ところで。
何回か書きましたように電源をONしたあとの最初のIコマンドの実行では”FF”エラーが発生していないということについてなのですが(E:92のエラーのことではありません)。
PIC18F2550のData SheetによるとLATAの値はPower−on Resetでは「わからない」となっています(前回参照)。
文字通りに解釈すれば25%の確率でRA3=0、RA2=1になる可能性があります。
繰り返しテストをしていたらあるいは電源ON後の最初のIコマンドの実行でも”FF”エラーになったかもしれません。
しかし。
上記のプログラム修正を行ないましたから今となってはそれはもうどちらでもよいことだと思います。
あえてそのことを確かめる必要はもうありませんでしょう。

最後に。
せっかくプログラムを修正したことですから念のために、もうエラーが発生しないということを確かめておきましょう。

ROコマンドでTEST24.BINをファイルオープンしてRBコマンドでデータを読みました。
2バイト目のデータは”90”です。
ここでEコマンドでプログラムを終了しました。
IN 82を実行すると”7D”が表示されました。
今までならこの状態でJP A000を再実行しそこでIコマンドを実行するとエラーが発生して”FF”が表示されました。
しかしプログラムを修正しましたからIコマンドは正しく実行されエラーは発生しなくなりました。

もうひとつ。
念のためにリセット後の信号をCPLDロジアナで観測しました。

[第104回]でお見せしたCPLDロジアナの波形ではリセット後40μsあたりでRA3(PROBE2)がLになっています。
それはその直前にIN 82で”7D”が表示されたときの波形ですが、同じ条件でもプログラムを修正した結果リセット後はRA3もRA2(PROBE3)もずっとHのままです。

リセット後490μsのところでRA3(PROBE2)がLになりました。

ここでPIC18F2550が初期設定を完了したことを示しています。
ここは今までと変わりません。
しかし今までならばRA3(PROBE2)=L、RA2(PROBE3)=Hを受けてND80Z3.5側はPC1(PROBE0)=H、PC0(PROBE1)=Hにするところですが変化がありません。
ND80Z3.5側のプログラムはPIC18F2550のリセット解除後に約9msのWAITルーチンを実行するようにプログラムを修正しました。
そんなに長く待たなくても2〜3msでも十分かと思ったのですがたまたま他のところで使うために9msのwaitサブルーチンがあったのでそれをCALLするようにしました。

ちょうど9ms後にPC1(PROBE0)とPC0(PROBE1)がHになりました。

PIC18F2550はそれを受けてRA3(PROBE2)をHにし、さらにND80Z3.5側がそれを見てPC1(PROBE0)=L、PC0(PROBE1)=Lにしたことが確認できます。

やっと。
これにて一件落着です。
いつもでしたら金麦で乾杯!というところですけれど。
ええ。
それはもちろんそうしますけれど。
結局のところしっかりData Sheetを確認しないで思い込みでプログラムを書いてしまったことがエラーの原因だったことがわかったわけで。
なんとも苦い乾杯であります。

そういえば。
金麦も増税で値上がりしてしまいましたですね。
値上がり前に買い込んだ分も残り少なくなってきました。
まことにお代官様はワルでいらっしゃいます。

PICBASICコンパイラ[第106回]
2023.11.27upload

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