目次PIC回路集カウントダウン・タイマー


カウントダウン・タイマー ソフトデバッグ説明




以下ではMPLABを使用したソフトウェアデバッグ作業のポイントを書きます。
デバッグの進め方はステップデバッグ方法とブレークポイントによるデバックを併用して行います。
それらの方法は「LEDフラッシャー」、「サインボード」のページを参照して下さい。

ここでは、デバッグを進めるために処理ステップの一部を変更する方法を紹介します。

疑似命令によるアッセンブル指定

    MPLABのアッセンブラーでは'IFDEF'疑似命令があります。この命令を使うとラベルを定義するかどうかによりアッセンブルする範囲を指定することができます。
#define  _debug

(1)
#ifdef _debug
        movlw   d'255'
#else
        movlw   d'43'
#endif

(2)
#ifdef _debug
        movlw   d'255'
#endif

(3)
#ifndef _debug
        movlw   d'255'
#else
        movlw   d'43'
#endif

(4)
#ifndef _debug
        movlw   d'255'
#endif

左の例は'#define'で'_debug'というラベルを定義しています。
その場合、#ifdef, #ifndef, #else, #endifで指定されているステップのアッセンブル状態が変わります。

(1),(2)の場合、'_debug'ラベルが定義されているので、#elseまたは#endifまでのステップ(赤色)がアッセンブルされます。#elseから#endifまでのステップ(青色)はアッセンブルされません。
#ifdefとは「もし、ラベル(_debug)が定義されていたら」という意味です。
#elseは「そうでなければ」という意味です。
ですから、(1)は「もし、_debugというラベルが定義されていたらmovlw d'255'をアッセンブルし、そうでなければ(ラベルが定義されていなければ)movle d'43'をアッセンブルする」と言うことになります。

(3),(4)はその逆です。#ifndefのnはnot(否定)の意味です。
ですから、(3)は「もし、_debugというラベルが定義されていなければmovlw d'255'をアッセンブルし、そうでなければ(レベルが定義されていたら)movlw d'43'をアッセンブルする」と言うことになります。

#endifを忘れないようにします。

この疑似命令はアッセンブルするかしないかの指定で、処理の流れを変えるものではありません。C言語などのような論理IFではありません。

今回はラベルとして_debugを使用しましたが、特に規定されているわけではありません。分かり易いラベルを使用します。

実際のアッセンブル結果の一部を以下に示します。赤文字の部分がアッセンブルされている行です。

_debugラベルを定義した場合 (デバッグモード)
LOC  OBJECT CODE     LINE SOURCE TEXT
  VALUE
                      00060 #DEFINE  _DEBUG

                      00153 #IFDEF _DEBUG
0042   30FF           00154         MOVLW   D'255'          ;(Debugging step)
                      00155 #ELSE
                      00156         MOVLW   D'43'           ;Set Hard timer value
                      00157 #ENDIF

                      00173 #IFNDEF _DEBUG
                      00174         BTFSC   PORTA,RA4       ;Stop switch ON ?
                      00175 #ENDIF
_debugラベルを定義しない場合 (本番モード)
LOC  OBJECT CODE     LINE SOURCE TEXT
  VALUE
                      00060 ;#define  _debug

                      00153 #IFDEF _DEBUG
                      00154         MOVLW   D'255'          ;(Debugging step)
                      00155 #ELSE
0047   302B           00156         MOVLW   D'43'           ;Set Hard timer value
                      00157 #ENDIF

                      00173 #IFNDEF _DEBUG
0051   1A05           00174         BTFSC   PORTA,RA4       ;Stop switch ON ?
                      00175 #ENDIF
    デバッグ用のラベルを定義しない場合には#defineの先頭にセミコロン(;)を付けて、コメント行にします。


疑似命令の設定箇所
    今回のソフトでは以下の箇所にデバッグ用の判定を入れています。
    BCDスイッチの読み取り部:実際にはBCDスイッチを接続していないので、デバッグ用に疑似入力データを設定しています。
    タイマー値の設定部: 実際の設定値にするとタイマー割り込みに時間がかかります。
    デバッグ時にはTMR0を255にして最短にし、割り込み回数の判断も2にしてデバッグの時間を少なくしています。
    ストップスイッチの読み取り部: MPLABの入力ポート条件は'0'に固定されています。(そうでないのかもしれません)
    そのままでは常にストップスイッチが押された状態になり、カウンターがタイムアウトする前にカウンターの停止動作になってしまいます。ですから、デバッグ時にはストップスイッチの読み取りステップを無効にしています。
    待ち時間サブルーチン呼出部:デバッグ時には1ミリ秒待ち時間サブルーチンの呼び出しをスキップしています。



ブレークポイントによる動作確認

    デバッグモードでアッセンブルしたプログラムをブレークポイントにより動作確認してみます。
    ブレークポイントはPC=009Bh009Dhに設定します。

    リセット後、 ボタンを押す毎にRAMメモリの0C, 0D, 0E, 0Fの内容が以下のように変化します。
    00 00 00 01 の時はPC=009Bhに停止します。PC=009Dhはタイムアウトチェックを行った後のステップなので、0Fが01の時には-1した結果が0なのでタイムアウト処理にジャンプします。

    0C0D0E0FRAMメモリアドレス
    01000000
    00090509
    00090508
    00090507

    省略
    00000001タイムアウト処理にジャンプ