タイマー0の使い方(その2)


【カウンタとして使う】

PICのタイマーは入力として内部クロック信号以外に、外部からの
パルス信号を使うことも 出来ます。
その入力ピンが、RA4(T0CKI)です。  これを使うと、外部信号の
カウントをすることが出来、人数カウンターや、周波数カウンターなど
を作ることが出来ます。
 ここではまず、易しい人数や事象のカウンタを作る方法の紹介と、
比較的難しい周波数カウンタとして動作させる方法の両方を紹介し
ます。

【PICのカウンタの内部構成】

 実際のPICの内部カウンタの構成は下図のようになっています。
 ここでRTE,RTS,PSAという信号は内部の切替制御信号で、OPTION
 レジスタで指定します。   一度指定すればそのまま電源が切れる
 まで、つまりRESETがかかるまでは保持されます。



ここで各々の意味を説明します。
 ・RTS:入力切替
  カウンタへの入力信号を内部クロックにするか、外部信号にするか
  の指定で、カウンタとして使う時には外部とします。
 ・RTE:エッジ切替
  入力信号の立上がりか立下がりどちらのエッジでカウントアップを
  するかを指定します。  信号が入った時にカウントアップするので
  立ち上がりエッジとしておきます。
 ・PSA:プリスケーラ切替
  プリスケーラカウンタを使うか使わないかを指定します。プリスケー
  ラはカウンタTMR0の前段に付くカウンタで、高速に動作することが
  できます。 その代わり、プリスケーラはプログラムで読み出すこと
  が出来ないので一つづつのカウント表示は出来なくなります。
  つまり、プリスケーラを8カウント動作と指定すると、8カウント単位
  でしか表現できないことになります。プリスケーラは8ビットカウンタ
  となっているので、最大256カウントのプリスケールが出来ます。
  プリスケールの動作指定はOPTINレジスタのPS0,1,2の3ビットで行
  います。 2,4,8,16,32,64,128,256の8通りのプリスケール値が指定で
  きます。
 ・TMR0:カウンタ本体
  内部カウンタ本体で、8ビットのカウンタです。従ってこれだけだと
  256カウントが最大値ということになります。
  プリスケーラの最大と合せて16ビットつまり65,535カウントが最大
  値となります。
  カウンタへの条件設定などした時には常にTMR0はゼロクリアされ
  ます。またカウンタがオーバーフローした時にはオーバーフローフラ
  グとしてINTCONレジスタ内のT0IFビットが"1"となります。
  また割込みを許可していればこの時点で割込みが発生します。
  このT0IFビットはプログラムでCLEARするまで1のままを保持します。
  従って、オーバーフロー処理でこれを0 CLEARしないと次のオーバー
  フローが分からなくなります。


【カウンタの性能】

 PICの内部カウンタ動作がどれほど高速に動作するかは、規格表から
下記の様になります。前提はクロックは10MHzとします。
結論からいうと、プリスケーラ無しの時は、最大2.3MHz プリスケーラ
付きの時は、最大18MHzとなります。

 TMR0カウンタ本体 : 最小パルス幅=(クロックサイクル)+20nsec                                       =420nsec周期=2.38MHz
 プリスケーラ本体 : 最小パルス幅=50nsec(電源5V)
                        =20MHz
 プリスケーラとTMR0の組み合わせの時
   : 最小パルス幅=((クロックサイクル)+40nsec)/(プリスケーラ値)
     プリスケーラ値毎に計算すると
          =440/2=220nsec=4.54MHz
          =440/4=110nsec=9.09MHz
          =440/8= 55nsec=18.1MHz(最大動作値)
          =440/16=27.5nsec=36.3MHZ>20MHz


【事象カウンタとする】

 まずカウンタの動作モードを設定するための初期設定から始めます。

【初期設定ルーチン】
   BSF    STATUS,RP0   ;Set page 1
   MOVLW   0E8H      ;set to no prescale
   MOVWF   OPTION_REG   ;OPTION register set
   BCF    STATUS,RP0   ;Set Page 0
   CLRF   TMR0      ;Clear TMR0

 [OPTIONレジスタの設定]
   RBPU   1 :PORTBのPullUp     =なし
   INTEDGE  1 :INT割込み信号のエッジ =立ち上がり
   RTS    1 :入力の選択      =RA4ピン指定
   RTE    0 :TMR0のカウントエッジ =立ち上がり
   PSA    1 :プリスケーラ有無   =無し
   PS1〜3  0 :プリスケーラ値    =無指定

次にカウンタ結果を読込む方法です。
TMR0だけだと8ビットカウンタですので256カウントが最大カウント数
です。しかし、オーバーフローフラグがあるので、これを使えばプログラ
ムでオーバーフローフラグを常に監視することでカウンターのバイト数
を任意に拡張することが出来ます。
下記例はBYTE0,1の2バイトのカウンターとなります。

【オーバーフローフラグの監視ルーチン】

LOOP  BTFSS   INTCON,T0IF  ;get overflow flag    
    GOTO   SKIP      ;goto not overflow
    BCF    INTCON,T0IF  ;reset T0IF
    MOVLW   1       ;count up data   
    GOTO   NEXT
SKIP  NOP           ;dumy NOP
    NOP
    MOVLW   0       ;not count up data
NEXT  ADDWF   BYTE1,F    ;BYTE1+T0IF
    MOVF   TMR0,W     ;get TMR0
    MOVWF   BYTE0     ;set to BYTE0
    GOTO   LOOP

【周波数カウンタとする】

 「一定時間(例えば100msec)だけ外部信号のカウントをする。」という
ことが出来れば、周波数カウンタとなります。 従って、外部にゲート回路
を設け、一定時間をPICのソフトウェアで作りこのゲートの開け閉めを制御
します。
しかし、難しいのは、この一定時間を作っている間でも、周波数カウントは
一緒に間断なく継続しているように、ソフトウェアを動かさなければなけれ
ばならないところです。

【カウンタ動作ルーチン】
 カウント結果をBYTE1〜2の3バイトに格納する。プリスケーラ無しの
設定で前項の初期設定と同じ設定とする。100msecの一定時間だけ
カウントするためゲートの空いている時間をプログラムステップ数で
制御する。外部ゲートの制御はPORTBのRB0で行っている。

MESURE  CLRF    TMR0     ;counter reset
     BSF     PORTB,0   ;open GATE
     CLRF    OVRFLW    ;reset overflow flag
     CALL    LOOP     ;(249996+2steps)
     NOP           ;dumy NOP (249999steps)
     BCF     PORTB,0   ;close GATE(250000steps)
     MOVF    TMR0,W    ;get TMR0
     MOVWF    BYTE0    ;set to BYTE0
     RETURN

;オーバーフロー監視、カウントアップ
;一定時間の確保(100msec)

LOOP    MOVLW   08DH     ;loop counter 141
      MOVWF   LPCNT1
MESLP1   MOVLW   088H     ;set counter 136
      MOVWF   LPCNT2    ;set counter
MESLP2   BTFSS   INTCON,T0IF ;13 steps loop   
      GOTO    DUMY1
      BCF    INTCON,T0IF ;reset T0IF
      MOVLW   1      ;カウントアップ
      GOTO    NEXT
DUMY1   NOP           ;dumy NOP
      NOP           ;同じステップ数にするため
      MOVLW   0      ;カウントアップ無し
NEXT    ADDWF   BYTE1,F   ;BYTE1+T0IF
      RLF    BYTE1,W   ;carry to d0
      ANDLW   1      ;mask
      ADDWF   BYTE2,F   ;BYTE2+Carry
      DECFSZ   LPCNT2,F   ;check loop end
      GOTO    MESLP2    ;loop
      NOP
MESLP3   DECFSZ   LPCNT1,F   ;(13*LPCNT2+5)*LPCNT1
      GOTO    MESLP1    ;(13*136+5)*141=249993-1
      RETURN         ;+2=249994


さて次ぎは液晶表示器との接続とその制御ソフトについてです。


        目次ページへ