Renesas Synergy™

FAQ 1006558 : タイマを組み合わせたパルス間隔測定の具体的な実現方法はどうなるのか。[78K0,小ピンマイコン共通]

できるだけ誤差を小さくするために2つのタイマ/カウンタを組み合わせる方法を考えてみます。一つは一定の時間を測定するために使用し、もう一つはパルスをカウントするために使用します。さらに、CPUの割り込み応答時間の変動の影響を避けるためにパルスのカウント値をキャプチャすることを考えます。
[実現方法]
この方法を利用するには、時間計測にタイマHを用い、その出力をタイマ0のTI01nに接続してキャプチャに使用します。タイマ0ではTI00nに測定したいパルスを入力します。このときの構成を下図に示します。(外部でTOHnとTI01nを接続します。)



次に、タイマHで測定する時間を決定します。この時間が短いと、被測定パルスとの非同期による誤差の影響が出ますし、長すぎると変化の検出に時間がかかってしまいます。ここでは、1m秒毎に測定するものとします。タイマHで8MHzのクロックから1m秒周期の方形波を出力するには1/32に分周したものをカウント・クロックに使用します。それを125カウントで出力を反転すれば0.5m秒毎に出力が反転するので、1m秒の周期を得ることができます。
タイマ0はフリー・ランニング・モードで使用し、TI00nをカウント・クロックに指定します。また、TI01n入力をトリガ入力で使用して、CR00nにタイマ0のカウント値をキャプチャします。これで、キャプチャ毎にINTTM00n割り込みが発生するので、そこでCR00nの値を読み出して、前回の値を引くことで1m秒間のパルス数を知ることができます。

[タイマの設定例]
78K0S/KA1+を例にして具体的なタイマ関係の設定を示します。
タイマH1関係の設定は以下のようになります。

TMHMD1 : 00110001(10110001)   (インターバル・タイマで出力許可)
CMP01 : 124   (125カウント)
PM4.2 : 0   (兼用端子を出力に設定)
P4.2 : 0   (兼用端子の出力ラッチは0に)

タイマ00関係の設定としては以下のようになります。

PRM00 : 01000011   (TI010は立ち上がり、TI000をカウント)
CRC00 : 00000001   (CR000はキャプチャで使用)
TOC00 : 00000000   (出力機能は使用しない)
TMC00 : 00000100   (フリー・ランニング・モードで使用)
PM3 : xxxxxx11   (対応する端子を入力に指定する)


[プログラム例]
上記の初期設定が完了し、測定を開始するときには、TMHMD1レジスタのビット7のTMHE1ビットをセットします。これで、時間計測が開始するので、最初のキャプチャ割り込み(INTTM000)を待ちます。最初のキャプチャでは前回の値が分からないので、キャプチャした値を読み出すだけにします。2回目以降の割り込みで、今回のキャプチャ値から前回のキャプチャ値を引いて、1m秒間のパルス数を求めます。
C言語で記述する場合には先ず、以下の宣言を行なう必要があります。ここでは、SFR名称を使うことや割り込みを使用することの宣言、内部で使用する変数を宣言します。

#pragma SFR
#pragma NOP
#pragma EI
#pragma DI
#pragma INTERRUPT INTTM000 TM00INT
__interrupt void        TM00INT (void);
sreg static unsigned int OLDDATA;
sreg static unsigned int FREQ;
sreg static unsigned int tempbuff;

次に、使用するタイマ関係の初期設定を行ないます。
なお、ここでは簡単のために、ウォッチドッグ・タイマは停止させておくものとします。

/*
TMH1 mode set
*/
TMHMD1 = 0b00110001;    /* set interval timer mode      */
CMP01 = 124;            /* set interval time    */
PM4.2 = 0;              /* set TOH1 enable              */
P4.2 =0;
/*
TM00 mode set
*/
PM3 = 0b11111111;
PRM00 = 0b01000011;             /* set TI010 edge and count CLK */
CRC00 = 0b00000001;             /* use CR000 to capture mode    */
TOC00 = 0b00000000;             /* no output is used    */

以上が初期設定です。この後、以下のように1回目のINTTM000をポーリングし、最初のキャプチャ値を変数OLDDATAに保存します。その後、割り込み可能にすることで、1m秒毎にキャプチャ動作が起動し、INTTM000が発生します。

TMC00 = 0b00000100;             /* start TM00 as free running   */
TMHE1 = 1;                              /* start 1msec timer    */
TMIF000 = 0;                    /* clear INTTM00                */
while(TMIF000 == 0){
NOP();                  /* wait for the first capture   */
}
OLDDATA = CR000;                /* get initial value    */
TMIF000 = 0;
TMMK000 = 0;                    /* enable INTTM000              */
EI();                           /* enable interrupt             */

キャプチャ割り込みが発生すると、以下の割り込み処理関数が起動され、前回のキャプチャ値との差を変数FREQにセットします。

__interrupt void        TM00INT (void){
tempbuff = CR000;               /* read captured value  */
FREQ = tempbuff - OLDDATA;      /* get pulse number     */
OLDDATA = tempbuff;             /* change TM00 value    */
}

注意

タイマ0でパルスをカウントする場合には、そのロウ・レベル/ハイ・レベルの幅に制限があります。幅としては、内蔵周辺クロックの2周期+100n/200n秒以上必要です。
電源電圧が4V以上で8MHzの周辺クロックの場合には350n秒以上、2.7V以上で8MHzの場合には450n秒以上のハイ/ロウ・レベル幅の信号しかカウントできません。
他にご質問がございましたら、リクエストを送信してください