今度は割込

PIC16F716 の工作の続きです。
今日は割込の実験をしました。Timer2 にはプリセットカウンタがあるので、これを使うことにしました。問題は、PR2 レジスタの設定値とカウンタの実際の振舞いについてです。マニュアルを見ると、TMR2 が PR2 に等しくなると 0 にリセットされるとあるのですが、そのタイミングが良く分かりません。そこで今度は Mid-Range MCU Family Reference Manual (33023a) というドキュメントを読んだところ、"Timer2 increments from 00h until it matches PR2 and then resets to 00h on the next increment cycle." という記述を見つけました。つまり、TMR2 による割込周期を prescaler 出力の 100分周にしたい場合は、PR2 を 100 - 1 = 99 にすれば良い、ということになります。
しかし疑い深い私は、実験で確かめてみることにしました。PR2 をできるだけ小さな値(1 とか 2 とか)に設定し、割込周期を周波数カウンタで計れば良いのですが、そうすると割込の頻度が高すぎて、割込を取りこぼす可能性がでてきます。いろいろ実験して、prescaler を 16 とし、PR2 を 4〜10くらいで評価してみました。確かに、割込周期が (PR2 + 1) になることを確認できました。
明日(以降)は、LED を増やしてデバッグ表示ができるようにして、それから A/D 変換を試してみようと思っています。

周波数カウンタって便利

秋月で買ったデジタルテスタ METEX P-16*1ですが、非常に重宝しています。特に 60MHz まで計れるという周波数カウンタが最高です。PIC のクロック*2発振周波数を確認したり、割込周期を確認したりと、非常に便利に使っています。もう一つくらい、予備に買っておくかなあ。

今日のコード

まだまだ実験的なコードですが、備忘録として書いておきます。

#include <htc.h>

__CONFIG(XT & WDTDIS & PWRTDIS & BORDIS & UNPROTECT);

volatile int count = 0;

int
init(void)
{
        TRISB  = 0x00;
        INTCON = 0x40;
        PIE1   = 0x02;
        T2CON  = 0x04;
        PR2    = 100 - 1;
}

void interrupt
isr(void)
{
        if (TMR2IF) {
                count ++;
                TMR2IF = 0;
        }
        
}

int
main()
{
        init();
        ei();
        for (;;) {
                PORTB = 0xff;
                while (count < 5000)
                        ;
                count = 0;
                PORTB = 0;
                while (count < 5000)
                        ;
                count = 0;
        }

        return 0;
}

*1:2,100円。

*2:セラロックで発振させているもの。