0

SDCC コンパイラを使用しています。

私が達成しようとしているのは、独自の割り込みハンドラー中に、モード 2 の自動リロードで Timer0 を再構成することです。Cコードは次のとおりです。

void reconf(void)  __interrupt(1){
    TR0=0;
    TH0=0xC0;
    TL0=0xC0;
    TR0=1;
}

質問は次のとおりです。

  1. モード 2 の自動リロード モードで、独自の割り込みハンドラの実行中に、Timer0 の TL0 と TH0 を再構成することはできますか?

  2. 再構成中に Timer0 を停止する必要がありますか? 中断中に実行されていないため、停止する必要はありませんか?

  3. 割り込みルーチンが開始する前に、TH0 と TL0 の値がスタックにプッシュされますか? これらの値がスタックにプッシュされ、ルーチン ハンドラーの実行中にこれらの値を再構成する場合、これらの値は、割り込みからの終了時にスタックからポップされた値によってオーバーライドされますか?

4

1 に答える 1

1

TR0質問に答える前に、 、TH0、およびが何であるかを指摘する価値があると思いますTL0。それらは、関数にローカルな変数でも、スタック上にある変数でもありません (ほとんどの 8051 アプリケーションにないコール スタックがあると仮定します -- メモリ オーバーレイを検索します) これらは特殊機能レジスタで、通常はSFRと略されます。SFR について詳しく読むことができますが、質問の目的のために、スコープの観点からそれらをグローバル変数として扱うことができます。

  1. TL0タイマー 0 ペリフェラルの割り込みハンドラ内を含め、レジスタとTH0レジスタはいつでも変更できます。

  2. 値を変更するためにタイマーを停止する必要はありませんが、停止している間もカウントし続けることに注意してください。これは、意図したものとは異なるタイマー値になる可能性がある場所で、下位バイトがロールオーバーしているときに書き込みを行っている場合に問題になる可能性があります。

    <previous code>  // Timer increments to 0x12fe
    TH0 = 0xff;      // Timer is now 0xffff
                     // Timer increments to 0x0000
    TL0 = 0x52;      // Timer is now 0x0052
                     // Timer increments to 0x0053
    

    タイマーを 0xff52 に設定しようとしましたが、0x0052 になりました。これは極端な例ですが、リスクはあります。TL0最初に の後にを書くことでリスクを軽減できますがTH0、タイマーをオフにするのが最も簡単な解決策です。

  3. TL0とがグローバル スコープの SFR であることがわかったのでTH0、スタックやその他の関数引数受け渡しメカニズムが SFR に干渉することを心配する必要はありません。

于 2013-09-25T20:11:57.277 に答える