【シミュレーションその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)