Renesas Synergy™

FAQ 1006550 : 同じ条件で1u秒程度の測定精度が必要な場合にはどうすればよいか。

1u秒程度の精度にするには、8MHzのクロックを1/4に分周した0.5u秒のカウント・クロックに設定する必要があります。ところが、この場合には約32m秒までしか(OVFフラグを使用しても約65m秒)カウントできません。
ここでは、さらに長いパルスの測定への対応方法を考えます。タイマ00がオーバフローしたら、上位の桁をカウントアップすることで、より長い時間の計測が可能になります。上位桁として8ビットの変数を追加することで8.3秒までの時間が計測可能になります。(カウント・クロックを8MHzにしても約2秒まで計測可能です。)
しかし、タイマ00にはオーバフローを示すフラグはありますが、割り込みがありません。そこで、CR000をコンペア・レジスタとして使用し、これをオー バフロー割り込みの代わりに使用します。つまり、CR000レジスタに0FFFFHを設定しておくと、タイマ00がFFFF→0000になったところで割 り込みを発生できます。
この場合に注意する必要があるのが、CR000レジスタの一致割り込みとCR010レジスタのキャプチャ割り込みが同時に発生したときです。割り込みは多重割り込みを使わない限りは、先に受け付けたものが優先されます。ところが、ある割り込みを処理中に発生した割り込みは保留され、処理中の割り込みが完了したときに最も優先度が高いものが受付けられます。従って、割り込み処理の中で割り込みの発生順序を判断する必要があります。割り込みがタイマ00の1周期分も保留されることはないとすると(そのような場合には元々正常な制御自体がきできません。)以下に示す割り込み競合動作の例が考えられます。 キャプチャの割り込みが~割り込み許可になるまでのタイミングで発生した場合が競合となります(タイマ00を「TI000端子の有効エッジでクリア&スタート」モードに設定しておくと、より前にキャプチャ割り込みが発生する場合にはタイマ00はFFFFにならないので、一致割り込みが発生しません)。

ここで問題はの場合のみです。この場合には上位の桁のカウントアップは必要ありません。しかし、以 降ではカウントアップが必要です。そこで、割り込みの優先度が高いCR000レジスタの一致割り込み処理の中でCR010レジスタへのキャプチャ割り込み 要求が発生しているかを確認し、発生していなければカウントアップを行ないます。また、キャプチャ割り込み要求が発生している場合には、キャプチャ値を確 認し、FFFF以外の場合のみカウントアップを行ないます。これにより、上位の桁とキャプチャした値との正しい組み合わせを得ることができます。

これを実際にC言語で記述してみます。この場合には、頭の部分で以下の宣言を行ないます。ここで、変数LENGTHはキャプチャした値を取り込んでおくための16ビットの領域です。8ビットの変数HIGHLENGTHはキャプチャした値に対する上位桁を取り込むもので、HIGHCOUNTは内部の作業用でカウントに用いている変数です。変数HIGHLENGTH変数LENGTHを組み合わせて24ビットでキャプチャした値が得られます。

#pragma SFR
#pragma EI
#pragma DI
#pragma NOP
#pragma INTERRUPT INTTM000 TM00INT
#pragma INTERRUPT INTTM010 TM01INT
__interrupt void        TM00INT (void);
__interrupt void        TM01INT (void);

sreg static unsigned int LENGTH;
sreg static unsigned char HIGHLENGTH, HIGHCOUNT;

初期化部分は初期設定部分と実際にタイマを起動して、割り込み禁止で最初のエッジを待ちます。その後、割り込みを許可して測定を始めます。

PM3.0 = 1;              /* TI000兼用端子を入力に設定    */
CRC00 = 0b00000100;     /* CR010をキャプチャで使用      */
PRM00 = 0b00110000;     /* 両エッジを指定               */
CR000 = 0xFFFF;         /* CR000はオーバフロー検出用    */
TOC00 = 0b00000000;     /* タイマ出力は行なわない       */
MK0 = 0x0FF;            /* 最初は割り込みをマスク       */
IF0 = 0x00;             /* 割り込み要求をクリア         */
/*
ここまでが初期設定、以下で実際にタイマ起動
*/
HIGHCOUNT = 0;          /* 上位カウンタをクリア         */
LENGTH = 0;             /* 結果の格納エリアをクリア     */
TMC00 = 0b00001000;     /* タイマ起動                   */
while(TMIF010==0){
NOP();          /* 最初のキャプチャ完了を待つ   */
}
IF0 = 0;                /* 割り込み要求フラグをクリア   */
TMMK000 = 0;            /* 割り込みマスクを解除         */
TMMK010 = 0;            /* 割り込みマスクを解除         */

EI();

INTTM000ではタイマ00のオーバフローを監視しています。

__interrupt     void    TM00INT (void){
unsigned int work;
if (TMIF010){           /* キャプチャ割り込みが発生中   */
work = CR010;   /* キャプチャ値を読み出し       */
if (work != 0xFFFF){
HIGHCOUNT++;    /*同時でないならカウント*/
}
}
else{
HIGHCOUNT++;    /* オーバフローだけならカウント*/
}
}

INTTM010で実際にキャプチャした値と上位桁の値を読み出して結果格納用の変数に書き込んでいます。実際に使用する場合には、この部分(赤字)を書き換えて下さい。

__interrupt     void    TM01INT (void){
LENGTH = CR010;         /* キャプチャした値を読み出し   */
HIGHLENGTH = HIGHCOUNT; /* 上位桁を読み出し             */

HIGHCOUNT = 0;          /* 上位桁をクリア               */
}

他にご質問がございましたら、リクエストを送信してください