【タイマーサブルーチン】 (2003/12/3)
この全体の中で、サブルーチンとして残ったのはタイマーだけです。
必要とされているのは、1秒間の待ち用のタイマーだけです。
1秒間というのは、PICのプログラムの世界から見ると、とてつもなく
長い時間です。そこで、下記のような3段階のタイマーで1秒を作る
ことにします。
(1)0.4msecのタイマー
(2)0.4msec×250 → 100msecタイマー
(3)100msec×10 → 1secタイマー
まず0.4msecを作るには、10MHzのクロックでPICを動かすと、1命令
の実行時間は、0.4μsec/サイクルですから、
0.4msec/0.4μsec = 1000サイクル を必要とします。
これをプログラムで作り出すには、とにかく、1000サイクルの実行時間
がかかるプログラムを作れば良い訳ですから、カウンターを設け、これ
を減算しながらループで繰り返すプログラムを作ります。
たとえば下記のリストのようにします。
まず、TIMLP1からGOTOまでは、5サイクルかかります。NOPは単純に
サイクルを増やすために挿入した命令です。
これを199回実行すれば、ほぼ1000回になります。200回としなかったの
は、前後に別の命令が必要だからです。これをCNT1のカウンターに
入れて、減算しながら繰り返します。
またDECFSZの最後の1回はスキップするのでGOTOは実行せず、NOP
相当の1サイクルになりますから-1しておきます。
前後の命令を加えると結局下記サブルーチン(のサブルーチン)は998
サイクルかかることになります。これで、ほぼ0.4msecが出来ることに
なります。998にしたのは、このサブルーチンを呼ぶCALL命令が2サイ
クル必要とするので、これを足して1000サイクルにするためです。
;0.4msec Timer Subroutine
TIM10
MOVLW 0C7H ;199回
MOVWF CNT1 ;ここまでで2サイクル
TIMLP1 NOP
NOP
DECFSZ CNT1,F ;このループは5サイクル
GOTO TIMLP1 ;2+5*199-1=996
RETURN ;996+2=998*0.4usec=0.4msec
さて次はこの0.4msecサブルーチンを使って、100msecタイマーを
作ります。
下記リストがその例です。100msec/0.4msec = 250 ですから、上
記サブルーチンを250回繰り返せばよいことになりますので、
CNT2のカウンタにF9(=249)を入れて、これを減算しながら繰り返
します。
ぴったり250にしなかったのは前後に実行しなければならない命令
が有るからです。この辺りになると、ぴったりの勘定にするのは
あきらめて大体にしています。(1秒間がそれほど正確である
必要が無いからです。)
; 100msec Timer Subroutine
TIM100
MOVLW 0F9H ;249回
MOVWF CNT2
TIMLP2
CALL TIM10 ;2+(1000+3)*249-1=249748
DECFSZ CNT2,F ;このループは1回1003サイクル
GOTO TIMLP2
RETURN ;+2=249750サイクル
最後にいよいよ1秒を作ります。
100msecのサブルーチンを10回繰り返せば良いのですから、
カウンターのCNT3に10を入れて繰り返します。
結果的に1秒よりほんのわずか短いタイマーが出来あがりです。
; 1sec Timer Subroutine
T1SEC
MOVLW 0AH ;10回
MOVWF CNT3 ;100msec * 10
T1LP
CALL TIM100
DECFSZ CNT3,F ;このループは100msec
GOTO T1LP
RETURN