TOP>MPLAB C18編(PIC18F1320)> LEDを点滅させる(TMR0割り込み)
LEDを点滅させる−TMR0割り込み−(C18)
(PIC18F1320)
更新日2009.3.28
前のページと同様0.5秒毎にLEDを点滅させますが、待ち時間はTMR0割込みにより作ります。
実験回路
|
・・ |
|
|
今回の実験回路は前のページと同じです。
クロックは内部クロックを使い8MHz動作としました。
LEDと直列の抵抗は、300〜800Ω程度の範囲であれば明るさが変わるだけで点滅の確認はできます。
-
-
| | 内部クロックを使いますのでOSC(15,16番)ピンは使いません。 また、MCLRを無効にしてMCLR(4番)ピンも使わない設定にしました。
|
- ブレッドボードに組んだ状態
-
| | 右のピンヘッダ周りは、回路図には有りませんがICSP(In-Circuit Serial Programming)用です。秋月のPICライタなどを使う場合は不要です。
|
|
プログラム
|
|
2つのLEDを0.5秒毎に交互に点滅させるもので、0.5秒の時間はTMR0割込みにより作成します。
TMR0は8ビットモードとしました。
プログラムの構造は、導入編の基本3パターンの中の、PIC16互換割込みを使うパターンをベースにしています。
今回のプログラムのポイントであるTMR0割込みについて以下に説明します。
-
このプログラムのTMR0割込みに関する部分を抜き出すと、以下のようになっています。
void timer_isr (void); // (1)
#pragma code low_vector=0x8 // (2)
void low_interrupt (void) {
_asm
GOTO timer_isr
_endasm
}
#pragma code
#pragma interruptlow timer_isr // (3)
void timer_isr (void) {
INTCONbits.TMR0IF = 0;
// TMR0割込み処理 // (4)
}
|
(1) | TMR0割込みルーチンの名前を定義
| (2) | 割込みベクタ「0x8」を定義し、アセンブラのGOTO命令でTMR0割込みルーチンに飛ばす
| (3) | TMR0割込みルーチンの定義
| (4) | ここにTMR0割込み発生時の処理を記述する
|
-
レジスタ | 用途など
| TMR0L | 8ビットのカウンタで、1命令サイクル毎にカウントアップし続け、最大値の255からオーバフローして0になる時TMR0割込みが発生
| INTCON | 割込みを有効にするビットと割込み発生時に設定されるビットから成る
| T0CON | TMR0の動作を規定するレジスタで、以下のような設定が可能
・TMR0有効/無効
・TMR0クロック選択
・8/16ビットモード選択
・プリスケーラ選択
|
-
-
Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 0〜255のカウンタ
|
8ビットのカウンタで、1命令サイクル毎に+1されます。(プリスケーラで変更できます)
そして、最大値の255から0に戻る時にTMR0割込みが発生します。
このレジスタの内容は設定可能で、例えば、TMR0Lに200がセットされていると、56命令サイクル (255−200+1)でTMR0割込みが発生します。
今回は、TMR0Lをフリーランさせます。(値を変更せず、プリスケーラやクロックで調整する)
【補足】
実際に設定する値は、オーバフロー後、次にTMR0Lに値を設定するまでの実行命令数を考慮する必要があります。(オーバフローしてもカウントアップは継続するため。)
更に、TMR0Lに値を設定した場合、その直後の2命令サイクル分はカウントアップが停止します。
また、プリスケーラを割り当てている場合は、TMR0を更新するタイミングでプリスケーラがクリアされます。
このような動作になるため、正確な時間が必要な場合は、TMR0Lをフリーランさせます。(値を変更せず、プリスケーラやクロックで調整する)
|
-
-
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オーバフローは発生していない
|
-
-
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)される。
|
|
-
- TMR0の時間に関する設定は以下のようにしました。
-
- クロックが8MHzですので、TMR0割込み周期は
-
1命令の時間 | : | 1/8×4 | =0.5uS
| TMR0割込み周期 | : | 0.5uS×256×64 | =8.192mS
|
- 従って、0.5秒間のTMR0割込み回数は
-
TMR0割込み回数 | : | 500mS/8.192mS | ≒61
|
(TMR0割込み61回で約0.5秒)
となります。
TMR0割込みルーチンでは、TMR0割込みを61回カウントしたらフラグ(flag.flag500mS)を立て、メインルーチンでこのフラグを判定してLEDをON/OFFさせています。
|