タイマー割り込みの使いかた平成20年8月17日 タイマー割り込みを使ったサンプルプログラム付録CD-ROMに収録されている、timer、dac、OTO_PRO1などのプログラムがタイマー割り込みを使用しています。 タイマー割り込みを使う方法タイマー割り込みを使うには、割り込み処理関数を登録するだけではなく、割り込み許可レジスタもセットする必要があります。
上のプログラムで、 PRM00 = 1; の3行は、内蔵周辺ペリフェラルのタイマー00の設定です。 MK0H.6は、TM000割り込みを許可するための割り込みマスク・フラグ・レジスタです。このレジスタはデフォルトではすべて1になっていて、0を書き込むことで割り込みが許可されます。 詳しくは、78F0730のユーザーズマニュアルの421ページを参照してください。 割り込み処理関数ではフラグレジスタをクリアする割り込み処理関数内では、割り込みで処理すべき内容を処理した後、割り込み要求フラグ・レジスタをクリアしてください。 詳しくは、78F0730のユーザーズマニュアルの419ページを参照してください。
また、割り込みルーチンの先頭と最後で、DEレジスタのPUSH POPを忘れずに行うようにしてください。
タイマー関連レジスタの設定方法78F0730で一番よく使われる内蔵周辺ペリフェラルは、おそらく「16ビットタイマー00」だと思います。 最低限設定すべきレジスタは、PRM00と、CRC000と、TMC00の3つです。あとのレジスタは設定しなくても何とかなります。 PRM00は、タイマーカウントに使うクロックの選択を行います。PRM00=1とすると4MHzで、PRM00=1とすると16MHzでカウントされます。 CR000はタイマーの周期を選択します。 PRM00=1とした場合は4MHzでのカウントとなるので、CR000=0x100にセットした場合は4000000/256 = 15625Hzでイベントが発生します。 TMC00を0x0Cにセットすることで、カウント動作が開始されます。
簡単に言えばPRM00=1の場合、割り込み周期 = (CR000の値) * 0.25 [μs]です。 タイマー割り込み周期の精度はCR000の値を4000にセットすれば、1ms周期での割り込みとなるはずですが、実際には揺らいでいます。 たとえば、次のようなプログラムを作った場合を考えます。これはメインのループの中でタイマー割り込みを使って動作するようなプログラムであって、USBから1文字受信したらループを抜けるようなプログラムです。
タイマー割り込みが発生する時間には、5μ秒程度のゆらぎがありました。 この原因は、trg_getrecvcount()関数にあります。 trg_getrecvcount()関数はUSBファームウェアの関数を呼ぶのですが、USBファームウェアの関数は内部でDIやEIを使っています。DIされている期間にタイマーが入っても応答することができないので、タイマー割り込みの発生時刻がゆらぐのだと思われます。 それならば、次のようにメインのループではUSB関係のルーチンは一切コールしないようにしてみました。
この場合、タイマー割り込みの発生時刻のゆらぎは1μ秒ほどになりました。 それなりに正確な周期で割り込みを発生させようとするならば、だいたい12〜16μ秒ならば限界になるようです。もちろん、複雑な処理をすればするほど長くなります。 最短にしたい場合でも、32μ秒くらいにしておくのがお勧めです。 まとめ@ タイマー割り込みの設定方法は、 PRM00 = 1; trg_regintsrv(TRG_INTID_BSITM000,intsrv_tim); A USBの関数を呼び出すと、割り込み周期が乱れる(5〜50μ秒くらい) B 正確な割り込み発生周期の限界は、だいたい12〜16μ秒 C USB関数を呼び出さなくても、USBから何か受信するだけで周期が乱れることがある。それが問題になる場合は、 trg_usbclose(); 関数を呼んでUSBを一切無効にしてみると良い。 D 割り込みルーチンの先頭と最後で、DEレジスタのPUSH POPを忘れずにする。
|
Copyright(C) 2008 NAITOU Ryuji. All rights reserved. 無断転載を禁ず