プログラムのデバッグ2

【シミュレーションその1】

まずシミュレーションをするために準備が必要です。
(1)PATAN1にブレークポイントを設定する
 Debug → Break setting で開くダイアログの中で、StartでPATAN1を
 選び、チェックマークをクリックしてブレークをかけます。
(2)実行状況の監視用にFile RegisterとSpecial Function Registerが
 見れる様にします。
   Window → File Registers
   Window → Special Function Registers
 これでそれぞれの窓が開きますので、適当な大きさにしてソース
 ファイルと一緒に見れるようにします。

(3)さていよいよシミュレーションの実行です。
 Debug → Run → Reset を実行し、次にDebug → Runとしますと実行
 を開始します。
 開始すると直ぐPATAN1を実行した直後でブレークするはずです。
 こうして、ブレークさせながら、その時のWレジスタや、PORTBの状態を
 確認することでデバッグをします。

 取り敢えずこのままF9キーを押すと続きを実行します。しかし、この後は
 1秒タイマーのルーチンの実行に入るので、とてつもなく長い実行時間を
 必要とします。
 これがシミュレータの欠点で、実時間では実行できず、何10倍もの時間
 を必要としてしまいます。そこで仕方が無いので、F5キーを押して実行を
 中断します。

(4)タイマールーチンの省略
 このままではシミュレーションに時間がかかりすぎてデバッグがやり難い
 ので、取り敢えず、タイマールーチンをはずして実行をさせてみます。
 はずし方は簡単で、CALL T1SEC 命令の書いてある行の先頭にコメント
 マークである「;」を追加してアセンブルし直すだけです。
 これでデバッグがし易くなりました。
 再度Reset、Runをさせて見ましょう。PATAN1でブレークし、再度F9を押す
 と、また直ぐ同じ所でブレークするはずです。
 しかし、まだ何かおかしい様です。パターン1のタイマー処理をはずした
 のにもかかわらず、2回目のブレークで止まりません。


(5)ステップモードで実行してみる
 再度最初から実行しなおします。(Reset、Runだけです)
 最初のブレークで止まったら、次はF7キーを押すと、F7キーを1回押す毎
 に、1個づつ命令を実行して行きますのでその都度、実行の流れや、Wreg
 の値を確認することが出来ます。

 そうやって、どのような順序で命令が実行されて行くかを確認すると、
 PATAN1の処理からRETURNすると、次のキー2の入力チェックでまた入力
 有りと判定されてパターン2の処理に飛んでしまっています。
 そうです、キー入力判定では、リセット後はPORTAには全て0が入力される
 ことになっているからです。
 これでは面倒なのでとりあえず、キー2の処理を省略するため、MAINの
 キー2の判定処理部分の2行をコメント行にしてしまいます。
 これで繰り返しブレークするようになったはずです。

 しかし、一寸おかしいですね? WregやPORTBの値がとんでもない値を
 示しています。何かおかしい。
 これで分かるのはどうもPATNA1の最初の8回終了の判定とPORTBの
 制御命令(BCF)がおかしい様です。


【シミュレーションその2】

(1)終了判定処理の間違い
 8回終了判定の命令を良く眺めてみると、SUBWFの引き算が逆になって
 います。これは良く間違うところです。
 SUBWF命令はWreg−F となります。

 また、BCF PORTB,BITC の命令も何か実行結果がおかしい様です。
 アセンブル結果でもWarning Messageが出ていました。
 この命令の使い方をよくよく見ると、BITCでビット位置を指定している
 つもりなのですが、このままではBITCの中味でなく、BITCのアドレス
 が使われていることになります。これはとんでも無い間違いです。
 でも良く間違う所です。
 早速修正しましょう。

(2)パターン1の処理の修正
 まず、PORTBの制御は、考えてみれば、BITCの1ビットだけ「1」に
 して、それを左へシフトすれば順次1が動いていくことになるので
 これをそのまま点灯制御に使えるはずです。
 ただし、点灯/消灯と0/1が逆転していますから、COMF命令で反転
 してPORTBへそのまま出力する必要がありますが。
 また、これを8回繰り返すと最後はBITCは全部0になってしまいます。
 そこでこれを8回の終了判定に使います。
 命令で書くとパターン1の処理は下記の様に出来ます。

PATAN1
    MOVF  BITC,W    ;BITCを取り出す
    BTFSC  STATUS,Z   ;0かチェック(8回終了か?)
    INCF  BITC,F    ;0だったら再度1をセット
    COMF  BITC,W    ;BITCを反転して取り出し
    MOVWF  PORTB     ;そのままPORTBに出力
    BCF   STATUS,C   ;Carryを0クリア
    RLF   BITC,F    ;BITCを左へシフト
    CALL  T1SEC     ;1秒タイマー
    RETURN

 ここでシフトする前にCarryをクリアしているのは、RLF命令が
 Carryを含めてロテートするため、BITCに余分な「1」がセット
 されない様にするためです。

 さてこれで再度アセンブルして確かめて見ましょう。これでWarning
 Messageもひとつ少なくなりました。

 これで、再度Runさせます。
 ブレークしたらレジスタ類を確認後、F9で続行させることを繰り返すと
 これできちんと期待通りの動きになったことが分かります。
 PORTBがFEからFD、FBとなって最後7FとなってまたFEにもっどている
 はずです。つまり下記のように0のところが点灯です。

   1111 1110 → 1111 1101 → 1111 1011 → → → 0111 1111

 
【シミュレーションその3】

(1)パターン2の修正
 今度はパターン2の方の確認をします。MAINのコメント行にした2行
 を元に戻し、今度はパターン1の方をコメントにしてしまいます。
 またPATAN2にブレークポイントを設定します。

 しかしその前にパターン2も BCF PORTB,BITC は間違っています
 から、修正する必要があります。
 BITCの使い方も終了判定の仕方もパターン1と同じにします。
 しかし、PORTBの制御内容はパターン1とは違うので考えなければ
 なりません。

 今度は前回のPORTBの内容は残したまま、新たにBITCの「1」の
 あるビット位置をさらに追加点灯させると考えれば、現在のPORTBと
 BITCの論理和をとれば良いことが分かります。しかし、0/1が逆なので
 実際は論理積にしてやる必要があります。つまりPORTBと0,1反転した
 BITCでいずれかが「0」のビットは0にするということです。
 これを実際の命令にすると下記のようになります。

PATAN2
    MOVF  BITC,W   ;BITCを取り出す
    BTFSS STATUS,Z  ;0かチェック(8回終了か)
    GOTO  PTN2LP   ;まだ、次へ
    INCF  BITC,F   ;再度1をセット
    MOVLW 0FFH    ;全ビット1
    MOVWF PORTB    ;全消灯
PTN2LP
    COMF  BITC,W   ;BITCを取り出して0,1反転する
    ANDWF PORTB,F   ;PORTBをANDをとってPORTBへ出力
    BCF  STATUS,C  ;Carry をリセット
    RLF  BITC,F   ;BITCを左へシフト
    CALL  T1SEC    ;1秒タイマ
    RETURN


(2)パターン2動作の確認
 この修正をして再度Runして確認します。
 きちんと動作することが確認できるはずです。
 PORTBが最初はFEでFC、F8と順次なり最後は00となってFEに戻る
 動作をするはずです。

  1111 1110 → 1111 1100 → 1111 1000 → → → 0000 0000

 これで発光ダイオードの制御論理はすべて確認できたことになり
 ます。 残るはタイマーです。



【シミュレーションその4】

(1)再アセンブル
 次はタイマーの動作確認です。前にコメントにしたCALL T1SECの
 コメントマークを削除して、再アセンブルします。

(2)Stop Watchの起動
 そしてタイマーの動作を確認するため ストップウォッチの窓を開き
 ます。タイマーは動作だけでなく、時間も測定する必要があります。
  Window → StopWatch → Taget Frequency → 10MHzに設定
 これで測定の準備が出来ました。

(3)再度Run
 再度プログラムをReset→ Runさせます、最初は直ぐPATAN2でブレ
 ークするはずです。
 そしてF9キーを押して続行させるとStopWatchがカウントを始めます。
 とても長い時間まって1secのカウントが終わると再度ブレークします。
 このときにStopWatchの時間を確認して1secになっていれば問題無し
 です。
 時間を待つとき、そのまま待っていると非常に長くかかるのですが、
 マウスを動かすと、時間が早く進みます。これで待つ時間を短くする
 ことが出来ます。
 これでストップウォッチの時間が合わなければ、カウンターの値を
 調整して合わせこみます。


 これでデバッグが完了しました。
 最終的なソースプログラムは下記となります。

  ★ ソースプログラム(修正後 ledcont1.asm)


   次のページへ      目次ページへ