315.タイマー1でコンペアマッチ割り込み


2002/10/25 【ソフトウエア編TOPに戻る】

前回PIC16F873のタイマー1で単純な16ビットタイマーの動作をさせてみました。そこではタイマーレジスタTMR1がオーバーフローすることによって発生する割り込み処理を利用しましたが、今回はカウント値があらかじめ設定した値と一致したことによって割り込みを発生させるコンペアマッチ動作についてご説明します。残念ながら、今回もPIC16F84Aではできません。


314−1.CCPの概要

ミッドレンジのPICにはCCPという機能が付いています。CCPとは(キャプチャ/コンペア/PWM)の頭文字を取ったもので、そのまんまキャプチャとコンペアとPWMの機能を行うためのものです。

CCPでは、機能の設定を行うためのCCPCONレジスタと、動作に関する値を保持するためのCCPRレジスタがあります。PIC16F873にはCCPが2チャンネルあり、それぞれCCP1、CCP2と称します。また、CCPCONレジスタやCCPRレジスタもそれに対応してCCP1CON、CCP2CONCCPR1、CCPR2と呼びます。

CCPCCPCONの設定によって以下の動作を行います。

■キャプチャ動作

PICのCCP端子(RC2/CCP1など)で立ち上がりエッジや立下りエッジといった入力信号の変化(イベント)があると、その時点でのタイマーレジスタTMRの16ビットの値をCCPRレジスタに保持(キャプチャ)します。イベントとしては立ち上がりごと/立下りごと/立ち上がり4回ごと/立ち上がり16回ごとの各種から選択することができます。

この機能は外部からのパルス幅を計測する場合などに用い、センサーからの応答を取り込んだりする場合に有効です。

■コンペア動作

タイマーレジスタTMRのカウント値が、あらかじめ設定しておいたCCPRレジスタの値と一致したときにコンペアマッチ割り込みが発生します。コンペアマッチ発生時にはCCP端子を1出力にしたり0出力にしたりする/TMRをゼロクリアする/AD変換を開始する(CCP2のみ)などの動作を行わせることができます。

■PWM動作

言わずと知れたパルス幅変調の波形を出力します。PWM動作ではPR2レジスタTMR2タイマーレジスタのカウント速度で周期が決定され、パルス幅はCCPR1LレジスタCCP1CONレジスタの設定で決定されて、CCP1端子から波形が出力されます。

 

今回は、これらの中からコンペアマッチによる割り込み処理についてご紹介します。キャプチャ動作とPWM動作については別の機会にご紹介します。

【先頭に戻る】


315−2.タイマー1を使ったプログラムその2 tmr1tes2.asm

それでは、タイマー1でCCP機能を使ったコンペアマッチ割り込み処理のプログラム例をご紹介します。内容的には314.タイマー1で16ビットタイマーのページでご紹介しているプログラムをベースに、コンペアマッチ動作に置き換えていますので、そちらも参照して下さい。

このプログラムでは、タイマー1のプリスケーラを8、タイマーカウンタTMR1の初期値を0000Hに設定してカウント動作をさせ、CCPR1にセットした8000Hの値と一致したことでコンペアマッチ割り込みを発生させます。発生した割り込み処理内で、RBの8BITから2進バイナリカウントを出力させます。コンペアマッチ割り込みが発生するとスペシャルイベントトリガと呼ばれる機能によってTMR1カウンタが0000Hに自動的にリセットされ、再びカウント動作が再開されます。

TMR1のオーバーフロー割り込みであれば104.856mSごとのカウント動作になりますが、今回はオーバーフローする前で割り込みが掛かるため、8000Hから計算すると約52.4mSごとの速さでカウントされるはずです。

プログラムはPIC16F873 用のみでtmr1tes2asm(ダウンロード)です。

 

;**********************************************************************
;TMR1 TIMER TEST2                                                          RIKIYA   2002.10.21
;DEVICE : PIC16F873
;CLOCK : 20MHz
;CCP1の割り込みを使った、TMR1インターバルタイマー動作
;PORTBからカウントアップ出力を行なう
;CCP1に設定した値とコンペアマッチするとTMR1のカウントをクリアして
;割り込み処理を行う。
;内蔵のTMR1カウンタだけで最長105mSのインターバルを発生する。
;**********************************************************************
          list p=16F873
          #include <p16F873.inc>

          __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF

          CNT1         EQU  20H                  ;アドレス20Hを変数CNT1とする。
;**********************************************************************
          ORG           0                              ;リセット時の開始アドレスセット
          GOTO        MAIN                        ;メインルーチンMAINにジャンプ
          ORG          4                              ;割り込みアドレスセット
          GOTO        INTR                         ;割り込みルーチンINTRにジャンプ

MAIN   BSF          STATUS                    ,RP0 ;メモリーバンクを1にセット
          MOVLW     080H                         ;Wレジスタに80Hをセット
          MOVWF     OPTION_REG              ;OPTION_REGに80Hをセット PULL UPなし
          BCF          PIE1,TMR1IE              ;TMR1オーバーフロー割り込み禁止
          BSF          PIE1,CCP1IE              ;CCP1コンペアマッチ割り込み許可

          CLRF        TRISB                       ;TRISBをクリア PORT-Bを出力にセット
          BCF          STATUS,RP0              ;メモリーバンクを0にセット

          MOVLW     30H                          ;Wレジスタに30Hをセット
          MOVWF     T1CON                      ;T1CONレジスタ プリスケーラ1:8 停止

          MOVLW     00H                          ;Wレジスタに00Hをセット
          MOVWF     TMR1L                      ;TMR1Lに下位8ビットデータをセット
          MOVLW     00H                          ;Wレジスタに00Hをセット
          MOVWF     TMR1H                      ;TMR1Hに上位8ビットデータをセット
          CLRF        CNT1                        ;CNT1変数を00Hにクリア

          MOVLW     0BH                          ;Wレジスタに0BHをセット
          MOVWF     CCP1CON                 ;CCP1CONレジスタ コンペアスペシャルイベント

          MOVLW     00H                          ;Wレジスタに00Hをセット
          MOVWF     CCPR1L                   ;CCPR1Lに下位8ビットデータをセット
          MOVLW     80H                          ;Wレジスタに80Hをセット
          MOVWF     CCPR1H                   ;CCPR1Hに下位8ビットデータをセット


          BSF          INTCON,PEIE             ;周辺割り込みの許可
          BSF          INTCON,GIE               ;全体割り込みの許可
          BSF          T1CON,TMR1ON        ;TMR1のTMR1ONビットをセット カウント開始

;***********************************************************************
;割り込みを待つループ
;***********************************************************************
LOOP
          NOP                                        ;何もしない
          GOTO       LOOP                      ;ラベルLOOPにジャンプ

;***********************************************************************
;割り込み処理
;***********************************************************************
INTR
          BCF         PIR1,CCP1IF             ;コンペアマッチフラグのクリア
          BSF         STATUS,RP0             ;メモリーバンクを1にセット
          BSF         PIE1,CCP1IE             ;コンペアマッチ割り込み許可
          BCF         STATUS,RP0            ;メモリーバンクを0にセット

          INCF        CNT1,F                    ;変数CNT1に+1する。
          MOVF      CNT1,W                    ;WレジスタにCNT1の値をセット
          MOVWF    PORTB                    ;PORTBへCNT1の値を出力

          RETFIE ;割り込みを許可してリターン

          END

以下のプログラム説明に出てくる各種レジスタについては、302.PICの命令とレジスタ一覧のページを参照して下さい。また、314.タイマー1で16ビットタイマーのページでご紹介したプログラムとの相違点だけを以下にご説明します。相違点は上のソースコード上で青字で表示しています。

 

■イニシャル部(ラベルMAIN)

          BCF          PIE1,TMR1IE              ;TMR1オーバーフロー割り込み禁止
          BSF          PIE1,CCP1IE              ;CCP1コンペアマッチ割り込み許可

両方の割り込み設定ビットは、PIE1レジスタにあります。ここではTMR1のオーバーフロー割り込みを禁止し、CCP1コンペアマッチ割り込みを使用可能としています。オーバーフロー割り込みはここでわざわざ禁止にすることもないのですが、禁止状態を強調する意味で記載しています。つまり、CCP1のコンペアマッチが検知されないと割り込みは発生しません。

 

          MOVLW     0BH                          ;Wレジスタに0BHをセット
          MOVWF     CCP1CON                 ;CCP1CONレジスタ コンペアスペシャルイベント

ここではCCP1CONレジスタによってコンペアマッチ割り込みでスペシャルイベントトリガが発生する設定にしています。具体的にはソフトウエア割り込みを発生させてTMR1タイマーレジスタを0000Hにクリアする動作に設定しています。

CCP1CONレジスタには以下の意味があります。

★CCP1CON(CCP1コントロール)レジスタの機能

CCP1の動作を設定します。

7 6 5 4 3 2 1 0
- - CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

CCP1XとCCP1Yは、CCPでPWM動作を行う場合のパルス幅を決定するために利用します。

CCP1M3〜CCP1M0の4ビット分でCCPの動作を以下のように設定することができます。

CCP1M3,2,1,0 モード 説 明
0000

CCPオフ

CCP1モジュールをリセットする。
0100 キャプチャ 立下りエッジごと
0101 キャプチャ 立上がりエッジごと
0110 キャプチャ 立上がりエッジ4回ごと
0111 キャプチャ 立上がりエッジ16回ごと
1000 コンペア 一致時にCCP1端子出力を1にセット(CCP1IFビットをセット)
1001 コンペア 一致時にCCP1端子出力を0にセット(CCP1IFビットをセット)
1010 コンペア 一致時に割り込み発生。(CCP1IFをセット、CCP1端子変化なし)
1011 コンペア スペシャルイベントトリガ TMR1をクリア、CCP1IFをセット
11xx PWM PWMモード

 

そして、以下の命令でCCPR1レジスタ8000Hに初期化しています。


          MOVLW     00H                          ;Wレジスタに00Hをセット
          MOVWF     CCPR1L                   ;CCPR1Lに下位8ビットデータをセット
          MOVLW     80H                          ;Wレジスタに80Hをセット
          MOVWF     CCPR1H                   ;CCPR1Hに下位8ビットデータをセット

つまり、TMR1タイマーカウンタ8000HになってCCPR1と一致するとコンペアマッチ状態になります。

 

■割り込み処理部

割り込み処理部では、CCPIF(CCP1割り込みフラグ)のクリアと、CCP1IE(CCP1割り込みイネーブル)のセットを行い、次の割り込み発生に備えます。

          BCF         PIR1,CCP1IF             ;コンペアマッチフラグのクリア
          BSF         STATUS,RP0             ;メモリーバンクを1にセット
          BSF         PIE1,CCP1IE             ;コンペアマッチ割り込み許可
          BCF         STATUS,RP0            ;メモリーバンクを0にセット

なお、TMR1オーバーフロー割り込みを使っていた前回のプログラムでは、

           MOVLW   00H                        ;Wレジスタに00Hをセット
           MOVWF   TMR1L                    ;TMR1Lに下位8ビットデータをセット
           MOVLW   00H                        ;Wレジスタに00Hをセット
           MOVWF   TMR1H                    ;TMR1Hに上位8ビットデータをセット

という命令を実行していましたが、今回は不要です。インターバルの周期を決定するのはCCPR1にセットする値なので、TMR10000Hのままでもいいのです。もちろん、TMR1にセットする値を変えてもインターバルの周期に影響を与えることができます。

【先頭に戻る】


314−3.実験風景

左の写真が実験風景です。といっても前回と同じ写真を使わせてもらっていますが...

動作的には思惑通り、前回の倍の早さでカウント動作を行ってくれました。CCPR1に書き込む値を変化させれば、それに追従してカウント動作の速度も変化します。

 

【先頭に戻る】


今回は、タイマー1でCCPのコンペアマッチのスペシャルイベントトリガ動作を行ってみました。

CCPではコンペマッチでCCP1出力端子の状態を変化させたりもできますし、この他にもキャプチャ動作やPWM動作、AD変換開始動作など様々な動作が可能なので、アイデア次第で面白い使い方が可能になると思います。それぞれのプログラム例については別の機会にご紹介していきたいと思います。

  【ソフトウエア編TOPに戻る】


【表紙に戻る】