目次>9章 PIC18F1320編 > TMR0割込みを使う(8ビットモードと16ビットモード)
TMR0割込みを使う− 8ビットモードと16ビットモード −
更新日2008.12.21
ここでは、PIC18のTMR0割込みを使って見ます。
PIC18のTMR0割込みは、PIC16と同様の8ビットモードに加え、16ビットモードが追加されています。
この2つの使い方の違いを見て行きましょう。
-
- このページの目次
-
1.実験回路
|
2.プログラムの仕様
|
3.PIC18の割込み
|
4.TMR0割込みで使うレジスタ
|
5.TMR0割込み(8ビットモード)
|
6.TMR0割込み(16ビットモード)
|
7.PIC18の勧め(6)
|
1.実験回路
|
・ |
1秒毎にLEDを点滅させて見るで使った回路と同じで、2つのLEDをRB0/RB1に接続します。
-
| |
680Ωの抵抗2本は、300Ω〜1KΩ程度の範囲であれば何でもOKです。
|
|
2.プログラムの仕様
|
|
RB0/RB1のLEDを1秒間隔で交互に点滅させます。
1秒の時間はTMR0割り込みにより作成します。TMR0割込みは、8ビットモードと16ビットモードの2種類を使って見ます。
|
3.PIC18の割込み
|
|
PIC18の割込みは、基本的にPIC16と同様です。
違いは、下の図のように割込みベクタのアドレスが変わっている点です。
-
ただし、PIC18では割込みに2つの優先順位を持たせる事が可能で、この新しい機能を使う場合は色々と違いがあります。それは別のページで実験して見る事にします。
今回は、割込みをPIC16互換で使用します。
|
4.TMR0割込みで使うレジスタ
|
|
TMR0割込みで使うレジスタをPIC16と対比すると下のようになります。
-
PIC16 | PIC18 | 用途など
| TMR0 | TMR0L | 8ビットのカウンタで、1命令サイクル毎にカウントアップし続け、最大値の255からオーバフローして0になる時TMR0割込みが発生
| INTCON | INTCON | ビットの意味は同じだがビットの名前が変わった
T0IE→TMR0IE
T0IF→TMR0IF
| OPTION_REG | T0CON | プリスケーラ選択とTMR0クロック選択に加え、以下のビットが追加された
TMR0ON | :TMR0有効/無効ビット
| T08BIT | :8/16ビットモード選択ビット
|
|
- TMR0L
-
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 0〜255のカウンタ
|
8ビットのカウンタで、1命令サイクル毎に+1されます。(プリスケーラで変更できます)
そして、最大値の255から0に戻る時にTMR0割込みが発生します。
このレジスタの内容は設定可能で、例えば、TMR0Lに200がセットされていると、56命令サイクル (255−200+1)でTMR0割込みが発生します。
今回は、クロックとして10MHzを使用していますので、1命令サイクルは0.4μSです。
従って、22.4μS(0.4μS×56命令サイクル)でTMR0割込みが発生します。
【補足】
実際に設定する値は、オーバフロー後、次にTMR0Lに値を設定するまでの実行命令数を考慮する必要があります。(オーバフローしてもカウントアップは継続するため。)
更に、TMR0Lに値を設定した場合、その直後の2命令サイクル分はカウントアップが停止します。
また、プリスケーラを割り当てている場合は、TMR0を更新するタイミングでプリスケーラがクリアされます。
このような動作になるため、正確な時間が必要な場合は、TMR0Lをフリーランさせます。(値を変更せず、プリスケーラやクロックで調整する)
|
- INTCON
-
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| GIE | PEIE | TMR0IE | INT0IE | RBIE | TMR0IF | INT0IF | RBIF
|
TMR0割込みで使うビットは以下の3つです。
その他のビットは、0にしておきます。
GIE | 全割込み禁止ビット 1:割込み許可(個々の割込み有効・無効ビットに従う) 0:全ての割込み禁止
| TMR0IE | TMR0割込み有効・無効ビット 1:TMR0割込み有効 0:TMR0割込み無効(禁止)
| TMR0IF | TMR0オーバフロー発生フラグ 1:TMR0オーバフローが発生した(割込み処理でクリアが必要) 0:TMR0オーバフローは発生していない
|
- T0CON
-
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| TMR0ON | T08BIT | T0CS | T0SE | PSA | T0PS2 | T0PS1 | T0PS0
|
TMR0ON | 1:TMR0有効 0:TMR0停止
| T08BIT | 1:8ビットモード 0:16ビットモード
| T0CS | TMR0クロックソース選択 1:T0CKIピン 0:命令サイクル
| T0SE | TMR0クロックソースがT0CKIピンの時、パルスの立ち上がり・立下りのどちらでカウントするかを選択 1:立下り 0:立ち上がり
| PSA | プリスケーラ使用有無 1:使用しない 0:使用する
| T0PS2-0
| プリスケーラ使用時の倍率指定
T0PS2-0 | 倍率
| 000 | 2
| 001 | 4
| 010 | 8
| 011 | 16
| 100 | 32
| 101 | 64
| 110 | 128
| 111 | 256
|
|
例えば、倍率64を設定すると、64命令サイクル毎にTMR0Lがカウントアップ(+1)される。
|
|
|
5.TMR0割込み(8ビットモード)
|
|
8ビットモードで動作させるには、T0CONのT08BITを1にします。
- それ以外のレジスタ設定は以下のようにしました。
-
- クロックが10MHzですので、TMR0割込み周期は
-
1命令の時間 | : | 1/10×4 | =0.4uS
| TMR0割込み周期 | : | 0.4uS×256×128 | =13.1072mS
|
- 従って、1秒間のTMR0割込み回数は
-
TMR0割込み回数 | : | 1000mS/13.1072mS | ≒76
|
(TMR0割込み76回で約1秒)
となります。
プログラムの処理で、今回のポイントをいくつか説明します。
- <初期処理>
-
初期処理では、T0CON,TMR0L,INTCONの設定を行います。
; ******** 初期処理 *****************************
init
;省略
;
MOVLW 0xC7
MOVWF T0CON ;TMR0 enable,8bit,presc256
MOVLW TMR0_i
MOVWF TMR0L
BSF INTCON,TMR0IE ;TMR0割込み許可
BSF INTCON,GIE ;全割込み許可
|
- <割込み処理>
-
割込み処理の開始アドレスを、08hに合わせます。
また、割込みの入り口と出口でレジスタの退避・復元を行いますが、通常は下のように3つのレジスタを対象にします。
; ******** 割込み処理 ****************************
ORG 0x0008 ;割込みベクタ
MOVFF STATUS,STATUS_TEMP ;save STATUS
MOVFF WREG,WREG_TEMP ;save WREG
MOVFF BSR,BSR_TEMP ;save BSR
;
;省略
;
MOVFF BSR_TEMP,BSR ;restore BSR
MOVFF WREG_TEMP,WREG ;restore WREG
MOVFF STATUS_TEMP,STATUS ;restore STATUS
RETFIE
|
- MOVFF命令は、PIC18で追加された命令で、以下の利点があります。
- ・STATUSレジスタを更新しない(PIC16のレジスタ退避・復元のような面倒な事が不要)
- ・命令のアドレス部が12ビットであり、バンクを考慮せずに全RAM領域にアクセスできる
- <GPR(汎用レジスタ)の定義>
-
データメモリはバンクを意識したアクセスが必要ですが、バンク0の前半はバンクを意識せずに使えます。(アクセスバンク)
また、割込みで使うレジスタ退避用の領域は、今回はMOVFF命令のみで使いますので、バンクを考慮せずに全RAM領域にアクセスできます。
従って、下のようなメモリ割り当てにしました。メモリに余裕があればレジスタ退避領域もバンク0の前半に割り当ててかまいません。
(今回はメモリに十分余裕がありますが意図的にこのような割り当てにしました。)
; ******** GPR *******************************
CBLOCK 0x080
WREG_TEMP ;WREG save area
STATUS_TEMP ;STATUS save area
BSR_TEMP ;BSR save area
ENDC
CBLOCK 0x000
CNT1S
flag
ENDC
|
|
6.TMR0割込み(16ビットモード)
|
|
次は16ビットモードで動かして見ましょう。
- 8ビットと16ビットの違いは、表現できる数が異なる点です。
-
8ビットで表せる数 | : 0〜255
| 16ビットで表せる数 | : 0〜65535
|
従って、16ビットモードの場合は、最大値の65535から0に戻る時にTMR0割込みが発生します。
- TMR0割込みの最大値は以下のようになります。(クロック10MHz,プリスケーラ256の場合)
-
8ビットモード | : 0.4uS×256×256 | = | 26.2144mS
| 16ビットモード | : 0.4uS×256×65536 | = | 6710.8864mS
|
16ビットモードで動作させるには、T0CONのT08BITを0にします。
こうする事でTMR0レジスタは16ビットモードになりますが、データメモリ(レジスタ)は8ビット単位でしかアクセスできません。
そこで、下図のようにTMR0レジスタを上位8ビットと下位8ビットに分けてアクセスするようになっています。
上位8ビットはTMR0Hを、下位8ビットはTMR0Lレジスタを介してアクセスします。
-
ただし、TMR0レジスタの上位8ビットとTMR0Hレジスタは単純には連携していません。
まず、簡単なTMR0の下位8ビットとTMR0Lですが、こちらは単純で、プログラムからTMR0LレジスタをREAD/WRITEすれば、そのままTMR0の下位8ビットにREAD/WRITEされます。(下図の水色)
一方、TMR0の上位8ビットのREAD/WRITE(下図の黄色の矢印)は、プログラムでのTMR0Hレジスタに対するREAD/WRITE(緑の矢印)に連動しません。
TMR0の上位8ビットとTMR0Hレジスタ間のデータ転送は、TMR0LレジスタへのREAD/WRITEに連動して行われます。(赤と黄色の矢印)
-
| |
TMR0への書き込み手順
- TMR0Hレジスタにデータを書き込む
- TMR0Lレジスタにデータを書き込む
TMR0からの読み出し手順
- TMR0Lレジスタからデータを読み込む
- TMR0Hレジスタからデータを読み込む
|
16ビットのTMR0レジスタに意図した値が書き込めるように、また正しい値が読み出せるようにするためこのような動作になっています。
16ビットモードで動作させるために、T0CONのT08BITを0にします。
- そして、TMR0レジスタへの設定値は、プリスケーラを256とすると、
-
オーバフローまでのカウント値 | : 1秒/0.4u秒/256 | ≒ | 9765
| TMR0設定値 | : 65536−9765 | = | 55771
|
- この、TMR0設定値を16進数に変換
-
- 従ってレジスタ設定は以下のようになります。
-
TMR0H | : | 0D9h
| TMR0L | : | 0DBh
| プリスケーラ | : | 256
|
基本的な流れは8ビットモードのプログラムと同じです。
|
7.PIC18の勧め(Vol.6)
|
|
- その7. TMR0は16ビットモードがサポートされた
- 従来の8ビットモードでは、長い時間(例えば1秒とか)を得るためにTMR0割込みを一定回数カウントするような事が必要でした。
PIC18では、16ビットモードがサポートされ、長い時間も1回のTMR0割込みで得る事ができます。
- その8. MOVFF命令はバンクの意識が不要
- TMR0割込みとは関係ありませんが、PIC18で追加された命令の一つであるMOVFF命令は、転送元・転送先のアドレスを12ビットで表現しており、全てのデータメモリに対してバンクを考慮せずにアクセスできます。
|