setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); // 262ms
の262msは、262msごとに割り込みをかける意味ですが、
なぜ、262msなのか、意味が分からず、あれこれ調べて
ました。
ある本で、
「PICのクロックを8MHZとすると最長262msのタイマー値を
得ることができます。」
の記事を見つけました。
やっと262msの意味がわかりました。次のように計算します。
タイマーの基準のとなる時間は、
(1/クロック周波数)×4
で求められます。私が、プログラムに使っている16F88の
クロックは8MHzなので、
(1/8Mhz)×4=0.5μs
「1」をカウントするために必要な時間は、0.5μsですが、
プリスケラ-(分周)との組みあわせで使います。
プリスケラ-を8とすると、「1」をカウントするための時間は、
0.5μs×8=4μs
になります。
TIMER1には、16ビットのカウンターを使うので、
最大、
16進数でFFFF(一桁を表すのに4ビット使うので、
4桁で16ビット)
10進数で65535回
を数えることができます。
目一杯数えると、
4μs(一回カウントするための時間)×65535回
=262140μs
262140μs=262.14ms
ということで、262msの時間がかかります。
やっと262msの数値がでてきました。
これを使うにあたっては、カウンターをセットする必要が
あります。
次のように、二つのレジスタを使って設定します。
が、
TIMER1H=0XFF
TIMER1L=0XFF
のように、設定すると最大の0XFFFF(16進数)の65535
の設定ができます。
アップカウンターなので65535を数えるには、
TIMER1H=0
TIMER1L=0
のようにします。
それでは、目的の数値を設定するには、
どうすれはいいのでしょうか。
TIMER1Hには、4桁の数字の上位の2桁を、TIMER1Lには、
4桁の数字の下位2桁をセットしますので、上位2桁と
下位2桁を取り出す必要があります。
たとえば、10進数で、8546の85を取り出すには、
8546÷100
をやって、小数以下を切り捨ててしまえば、目的の「85」
の数値を取り出せます。
これと同じことを、ビットをずらすという命令を使って実現し
ます。ビットをずらす命令は、2進数で考えますので、
4桁の数値を2進数にすると16桁になります。
○○○○ ○○○○ ○○○○ ○○○○
赤が目的の数値ですので、右に8こずらすと、
○○○○ ○○○○ ○○○○ ○○○○
となり、ずらした後には、0が挿入されますの、これで目的
の上位2桁を取り出せます。これをするには。
8546 >> 8
とします。つまり、85をTIMER1Hにセットするには、
TIMER1H=(8546 >> 8)
とすればいいわけです。
では、下位2桁を取り出すにはどうすればどうすればいいで
しょうか。
8546-8500
をすれば、46の数値がとりだせます。これを実現するのに、
やはり2進数で考えます。マスクをかけるというような言い方
をしたりしますが、「and」という演算をします。二つの数値を
比べて、次のような出力になりますから、
0と0は0
1と0は0
0と1は0
1と1は1
次のように、16進数で「OOFF」(2進数で0000000011111111)
とのAND演算をします。
すると上位2桁が0になって目的の下位2桁の数値が取り
出せます。実際は、次のようにします。
TIMER1H=(8546 & OX00FF)
これで、下位2桁の「46」をセットすることができます。
8546回数えさせるためには、
TIMER1H=(8546 >> 8)
TIMER1L=(8546 & OX00FF)
と言うように、2行に分けて、記述します。
難しかったです。ここまで理解するのに、3日ぐらいかかり
ました。