タイマー0の使い方


【タイマー0】

 タイマー0もPIC18xxxxシリーズでは強化されています。
強化ポイントは下記のようになっています。

(1) 8ビットモードと16ビットモードの両方が用意されソフトウェアで選択できる。
  カウンタが長くなったことで、長時間のインターバルタイマも可能になった。
  
(2) 8ビットの専用のプリスケーラが用意された。
  従来はウォッチドッグタイマと兼用であったが、専用になった。
  16+8で最大24ビットのカウンタとなった。

(3) 16ビットタイマを確実に読めるようになった。
  16ビットモードの時に上位バイト、下位バイトを同時に読み出せるように、
  ハードウェアで上位バイトをバッファするようにした。


【タイマー0の構成】

タイマー0の8ビットモードの時の構成は下図のようになります。
これまでと同じ構成ですが、プリスケーラがタイマー0専用になっています。
そしてTMR0に書き込むと、同時にプリスケーラもクリアされます。
TMR0がFFから00になるときに割込みが発生します。



タイマー0の16ビットモードの時の構成は下図のようになり、16ビットモードでは
8ビットのプリスケーラを加えると、全体で24ビットのカウンタとなります。
従ってかなり長時間のインターバルタイマも構成することが可能になりました。
そしてTMR0カウンタが、FFFFからから0000になるときに割込みが発生します。



16ビットモードの時には、タイマー0のカウンタの内容は上位、下位の2バイトで
Read/Writeします。このとき上位バイトは直接は読み書きしないで、TMR0H
レジスタを経由して読み書きします。
この上位バイトの読み書きのタイミングは、下位バイトであるTMR0Lレジスタと
同期するようになっており、読み出しの時には、TMR0Lを読むと、同時に上位
バイトがTMR0Hレジスタにコピーされます。
このため、従来下位バイトを読んで、次に上位バイトを読むまでの間で、上位バイト
がカウントアップしてしまうかもしれないという問題を回避できるようになりました。
つまりTMR0Lを読み込んでから、次にTMR0Hを読めば、TMR0Lを読み込んだ瞬間
の時の上位バイトが読み込めることになります。

書込みの時は、あらかじめ上位データをTMR0Hに書き込んでおき、それから下位
データをTMR0Lに書き込めば、そのタイミングで同時にTMR0Hからカウンタの上位
バイトに書き込まれます。 このとき同時にプリスケーラもクリアされます。

【T0CONレジスタ】

 タイマー0の機能強化により制御用のレジスタT0CONも機能追加されて下図の
ようになりました。
ここでは、TMR0ONとT08BITビットが追加されました。
T08BITが8ビットと16ビットのモード切替用の設定ビットです。
タイマー0を使わないときは、TMR0ONビットを0にしてOFFとすることで、余分な
消費電流を減らすことができるようになりました。





【アセンブラでの使用例】

実際のアセンブラでの使用例です。
機能としては、1桁のセグメント発光ダイオードに数値を表示します。
そして1秒周期のインターバルタイマの割込みで、その数値を+1し
9になったら0に戻ります。

メインの初期設定では、ポートの初期設定をしたあと、タイマ0の設定を
していますが、40MHzクロックで1秒周期の割込みを発生させています。
この初期設定で、高位レベルの割込みを発生します。





この1秒ごとのインターバル割込みの処理部分は下記のように
なります。この中で表示する数値を+1しています。
高位レベルの割込みなので、レジスタ保存、復帰は自動で行われます
ので、RETFIEでFast Returnを指定するだけです。






  ★上記の例題のソースファイルです。 timer0.asm


【タイマー用Cライブラリ関数】

CCSのPCHコンパイラで用意されているタイマ0用の関数には、下記のような
ものがあります。

関数書式 機能内容 と パラメータ

setup_timer_0(mode)
 またはsetup_counters(mode, ps)
(PIC18では使わないこと)

タイマ0の初期設定で、OPTIONレジスタに書き込む。
使うパラメータは下記。
mode
 動作モードとプリスケール値との2要素を
 ORで結合して指定する。
《動作モード》 mode
RTCC_OFF      タイマ0停止
RTCC_8_BIT      8ビットモード
RTCC_INTERNAL  内部クロック指定
RTCC_ETX_L_TO_H 外部入力信号の立上り指定
RTCC_EXT_H_TO_L 外部入力信号の立下り指定

《プリスケール値》 ps
RTCC_DIV_1  プリスケーラなし
RTCC_DIV_2  プリスケール2
RTCC_DIV_4   〃     4
RTCC_DIV_8   〃     8
RTCC_DIV_16   〃    16
RTCC_DIV_32   〃    32
RTCC_DIV_64   〃    64
RTCC_DIV_128  〃    128
RTCC_DIV_256  〃    256
《例》
  setup_timer_0(RTCC_DIV_2 | RTCC_EXT_L_TO_H);
  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64);

get_timer0()
 または
get_rtcc()

TMR0レジスタの現在値の読込み long型で返す。
ただし8ビットモードの時はint型で返す
《例》 whie (get_timer0() < 200);

set_timer0(value)
または
set_rtcc(value)

TMR0レジスタにvalueを書き込む。valueはlong型
たたし8ビットモードのときはint型
《例》 set_timer0(81);




【実際の使用例】

下記のプログラム例は、これらのタイマー関数を使った実際の例です。

《例1》
  タイマ0の約25msec周期の割込みを使って、発光ダイオードを点滅させた例です。
  アイドルループでも別の発光ダイオードを点滅させています。

    ★ タイマ0の使用例




  トップページへ