2

BoostC コンパイラで C を使用しています。コードがどれほど正確か心配です。以下の構成は、多かれ少なかれ 1Hz で動作します (肉眼で LED を使用してテスト)。(16f74 の Timer1 には、外部時計クリスタル 32kHz を使用します)。

誰か教えてくれるといいのですが…

以下のコードに調整が必要ですか? 最も近い CPU クロック周期の精度を測定する最も簡単な方法は何ですか? 1Hz 信号の精度を確実に確保するために、組み立てを行う必要がありますか?

タイマーは常にカウントされているため、タイマー ハンドラー (およびその他) の実行にかかる時間が問題にならないことを願っています。ハンドラーの実行に 1/32kHz 秒以上の時間がかからない限り、1Hz 信号は本質的に 32kHz Crystal の精度を持つでしょうか?

ありがとう

#define T1H_DEFAULT 0x80
#define T1L_DEFAULT 0
volatile char T1H = T1H_DEFAULT;
volatile char T1L = T1L_DEFAULT;

void main(void){

    // setup 
    tmr1h = T1H;
    tmr1l = T1L;
    t1con = 0b00001111; // — — T1CKPS1 T1CKPS0 T1OSCEN NOT_T1SYNC TMR1CS TMR1ON
    // ...

    // do nothing repeatedly while no interrupt
    while(1){}
}

interrupt(void) {

    // Handle Timer1
    if (test_bit(pir1, TMR1IF) & test_bit(pie1, TMR1IE)){

            // reset timer's 2x8 bit value
            tmr1h = T1H;
            tmr1l = T1L;

            // do things triggered by this time tick

            //reset T1 interrupt flag 
            clear_bit(pir1, TMR1IF);

    } else 

    ... handle other interrupts

}
4

1 に答える 1

2

若干の改善が見られます...

割り込み内のタイマーの開始は正確ではありません。割り込みでタイマーカウンターをセットすると・・・

    tmr1h = T1H;
    tmr1l = T1L;

...次に、精度が良くない現在の値をオーバーライドします。...使用するだけです:

tmr1h = T1H;  //tmr1h  must be still 0!

または、さらに良いことに、tmr1h レジスタの 7 番目のビットを設定するだけです。コンパイラは、この順序を次のような単一の asm 命令にコンパイルする必要があります...

bsf    tmr1h, 7

...tmr1 レジスタのデータが失われないようにします。これが複数の命令で行われる場合、ハードウェアは次の実行の間にカウンター値をインクリメントできるためです。

于 2011-06-25T10:23:30.913 に答える