PIC(4)-タイマー0割り込み機能

このエントリーをはてなブックマークに追加

本日は、PICを使用したタイマー割り込み機能です。

タイマー0割り込み機能は、一定周期で処理をしたい場合などに使用します。

下記のコードは、タイマー機能を使用して、50ms毎にLEDランプが点灯、消灯を繰り返す機能になります。


#include <xc.h>

// CONFIG
#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = ON
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config CP = OFF

//タイマー0割り込み
void interrupt isr(void)
{
    TMR0 = 0x3D;    //タイマー0初期値
    RB0 = RB0 ^ 1;  //電圧レベル反転
    T0IF = 0;       // タイマ0割込みフラグをクリア
}

//メイン
void main(void) {
    
    PORTA = 0xFF;
    PORTB = 0xFF;

    TRISA = 0xFF;
    TRISB = 0x00;

    T0CS = 0;       // クロック源を内部クロックに設定
    OSCF = 1;       //0:48kHz 1:4MHz

    PSA = 0;        // プリスケーラをタイマ0に割り当て
    PS2 = 1;        // プリスケーラ値を256に設定
    PS1 = 1;
    PS0 = 1;

    TMR0 = 0x3D;    //タイマー0初期値
    T0IF = 0;       // タイマ0割込みフラグをクリア
    T0IE = 1;       // タイマ0割込みの許可
    GIE = 1;        //全体的に割り込みの許可

    //メインループ
    while(1){}
}

それでは、プログラムのソースコードについて解説していきます。

今回は、メイン関数の他に、タイマー0割り込み関数が用意されています。

タイマーのカウントがオーバーフローした際に、タイマー0割り込み関数にとびます。

では、タイマーのカウント数について考えていきます。

今回、クロックは4MHzに設定しています。

内部クロックの場合、カウンタは4周期に1カウントするので、今回は1000000カウントできることになります。

この場合、LEDの点灯、消灯は1μsecになります。

今回は、50msecという設定なので、500000カウントすれば良い事になります。

ただし、タイマーのカウントは8bitしか用意されていません。

ようするに、256回までしかカウントできません。

そこで、プリスケーラを活用します。

プリスケーラは8bit用意されているので、これを活用すると256×256で65536カウントできます。

これなら50000カウントできるので、50msecの周期をつくれそうです。

50000カウンタをプリスケーラ値256で割ると、約195カウンタになります。

タイマーのMAX値の256カウントから195カウントを引いた値をタイマーの初期値にすることで、50msec後にタイマー0割り込みが発生するような機能が構築できます。

TMR0にカウンタの初期値を入力するので、TMR0=0x3Dとなっております。

このカウンタ値の設定は、メイン関数の部分の他にも、タイマー0割り込み関数でも設定しております。

T0CS、PSA、PS2、PS1、PS0、TMR0、T0IF、T0IE、GIEはタイマー0割り込みを行う為の設定になります。

タイマー0割り込みの設定については、ソースコードのコメントを参考にしてください。

OSCFは、内部クロックの設定になります。

コメントの通り、0の場合は48kHz、1の場合は4MHzになります。

実際に動作させると、LEDの点灯、消灯を繰り返す事ができました。

しかし、点灯、消灯の周期はどう確認すればよいでしょうか?

そこで、オシロスコープを使用します。

オシロスコープでの確認は次回行いたいと思います。