PIC16F84A タイマー割り込み


PIC16F84Aには、8ビットタイマーが内蔵されています。
これを用いて、タイマー割り込みが利用できます。

20140427_pic_timer0

タイマー割り込みを使用するには、下記の3つのレジスタを設定します。
INTCON
割り込み制御レジスタ
GIE (Global Interrupt Enable)
TMR0IE (TMR0 Overflow Interrupt Enable)

OPTION REG
オプション・レジスタ
T0CS (TMR0 Clock Source Select)
1 = Transition on RA4/T0CKI pin
0 = Internal instruction cycle clock (CLKOUT)
PSA (Prescaler Assignment)
1 = Prescaler is assigned to the WDT
0 = Prescaler is assigned to the Timer0 module
PS2-0 (Prescaler Rate Select)
 Prescaler Rate Select は、000 (1/2) から 111 (1/256) が設定できます。

TMR0
タイマー0 レジスタ
8ビットのアップカウンタです。
255を超えてオーバーフローしたときに割り込みを発生します。
0x00 (1/256) から 0xFF (1/2) が設定できます。
注意:分周比 は 256 – 設定値 です。

割り込み周期
割り込み周期は下記の計算式で求められます。
(Fosc / 4) * プレスケーラー分周 * タイマー分周

例えば、Fosc が 16MHZ で、プレスケーラー分周 が 1/256 で、タイマー分周 が 1/256 のときは、61 Hz (16.4 ms) です。
それより長い周期の割り込みが欲しいときは、プログラムでカウンタを作って、割り込みがN回起きたら、処理を実行するようにします。
例えば、1秒周期のときは、61進カウンタにします。
61 = 1 sec / 16.4 msec

プログラム例
1秒間隔でLEDを点滅させるプログラム

int main(void) {
    TRISA = 0x00;   // PortA all output
    TRISB = 0x00;   // PortB all output
    PORTA = 0x00;   // PortA all low
    PORTB = 0x00;   // PortB all low
    OPTION_REG = 0x07;  // 1/256
    TMR0 = 0;   // 1/256  
    INTCONbits.TMR0IE =1;   // TMR0 Overflow Interrupt Enable
    INTCONbits.GIE = 1; // Global Interrupt Enable
    while(1) {}     // endless loop
}
static void interrupt isr(void) {
    if (INTCONbits.TMR0IF == 1) {   // TMR0 Overflow
        INTCONbits.TMR0IF = 0;  // clear flag
        TMR0 = 0;
        if ( counter >= 61 ) {  // 1sec
            counter = 0; // reset counter
            PORTBbits.RB4 = is_led_on;  // set LED
            is_led_on = !is_led_on; // bit invert
        }
    }
}

プログラムは Github で公開してます。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です