[PIC]TMRモジュールを使用する(タイマー割り込み)

PICにはTimer0モジュールというものがあり、このモジュールはカウンタやタイマー処理として使用できます。
今回はPI15F84におけるタイマー処理について説明します。

Timer0モジュールの仕組み

Timer0モジュールは、カウンタ又はタイマーのどちらか一方として使用することが出来ます。
どちらのモードとして使うかはオプションレジスタ(0x81:OPTION_REG)の5ビット目にあるT0CSビットで指定することが可能で、このビットは以下の意味を持ちます。

OPTION_REG.T0CS(bit5)
 
1:RA4/T0CKI   -> カウンタモード
0:内部クロック  -> タイマーモード




タイマーモードとして使う場合は、通常はTMR0レジスタの値が1命令実行するたびにインクリメントされていきます。プレスケーラを使用すると、1命令単位ではなくN命令実行するたびにインクリメントさせる様に変更できるので、より長い周期でのタイマーを定義できます。


ただし、TMR0レジスタに値が書き込まれた時、直後の2サイクル分は値が加算されないことに注意が必要です(と、データシートに書かれていたのですが、シミュレータで実行する限り、直ぐに加算されているようです… 要確認。)


一方、カウンターモードの場合、TMR0レジスタの値は自動で変わりません。
その代わり、PIC15F84Aの場合、RA4の値が変わったら(エッジを検出したら)TMR0レジスタの値が変わります。

エッジには立ち上がりと立ち下りがありますが、どっちのエッジを取りたいかはOPTION_REGのT0SEビットで指定できます。

OPTION_REG.T0SE(bit4)
 
1:立ち下がりの検出を行う
0:立ち上がりの検出を行う



ちなみにOPTION_REGは81hなので、このレジスタに値をセットするときはBank1に切り替える必要がある事に注意してください。

タイマー処理を有効にする


タイマー処理の有効化は、具体的には以下のコードで行うことが出来ます。

    ;タイマ割込みを有効にする
    MOVLW       0F0h    ;タイマーの初期値を指定する
    MOVWF       TMR0
 
    BSF         STATUS, RP0 ; BANK1に切り替え
    BCF         OPTION_REG, T0CS    ; TMR0をタイマモードとして実行
    BCF         STATUS, RP0 ; BANK0に戻す



上記のコードを実行させると、OPTION_REGの値を設定した直後から、1命令実行するたびにTMR0レジスタの値が加算されていきます。
これでタイマーとしての実行は完了ですが、タイマーが期待した値になったかを定期的に監視(ポーリング)するのは面倒なので、通常はタイマーが特定の値になった時に処理を行います。

この為、上記に加えてタイマー割り込みの登録を行います。
割り込み関係の定義は、INTCONレジスタを操作する事で設定できます。

    BSF         INTCON, T0IE ; TMR0 interruptをenableにする
    BSF         INTCON, GIE  ; Grobal interruptをenableにする


PICには複数の割り込みがあるので、T0IEビットで”タイマー割り込みを有効”にした上で、GIEビットで”割り込みの仕組み自体を有効にする”という2段階での設定が必要となります。

この設定を行うことで、TMR0レジスタの値がFFから00に代わるタイミングで、割り込み処理が行われます。


割り込みを処理を記述する

PICでは割り込みが発生すると、PCが0x04番地に移ります。
ですので、割り込みの処理は必ず0x04番地から記述されている必要があります。

また、割り込みが行われた時、PICのハード側では割り込み前のPCだけが保存されます。
その他のレジスタを使用する場合は、割り込み処理の最初に自分でレジスタ情報を退避し、割り込み処理の最後に戻す必要があります。
特にWレジスタやSTATUSレジスタは何らかの命令を実行すると書き換えられてしまうので、退避・復元処理が必須です。

この退避・復元は一般的に行われる作業なので、下記のようなテンプレートを使用する事が多いです。

W_TEMP      EQU 0x??
STATUS_TEMP EQU 0x??
 
    ;レジスタの退避
    MOVWF   W_TEMP      ; Wレジスタを W_TEMPに退避
 
    SWAPF   STATUS, W   ; STAUSレジスタをSTATUS_TEMPに退避(上位4ビットと下位4ビットが反転される)
    MOVWF   STATUS_TEMP
 
 
    ;割り込み処理メイン
    ...
 
    ; 割り込みの再設定
    BCF INTCON, T0IF
 
    ;レジスタの復元
    SWAPF   STATUS_TEMP, W  ; STATUS_TEMP
    MOVWF   STATUS
    SWAPF   W_TEMP, F
    SWAPF   W_TEMP, W
 
    ; 割り込みから戻る
    RETFIE


関連記事

コメントを残す

メールアドレスが公開されることはありません。