これまでの実験では、処理のタイミングを合わせるために delay関数を使用してきました。しかし、delay関数を使用すると、delayが終わるのを待っている間はなにも処理をすることができません。これでは複数の処理を同時平行で行うことができず、複数サーボの駆動や通信を同時に実現することができなくなります。そこで、タイマ割り込みを使用して(比較的)正確なスケジューリングと無駄な待ち時間の削減に挑戦してみましょう。
割り込み(interrupt)というのは、主として行っている処理を一旦停止して別の処理を行うことを言います。割り込み処理が可能なら待ち時間に別の処理ができるので、CPUの処理効率を高めることができます。もちろん、割り込みを使わなくてもプリエンプティブ(※)なマルチタスクOSを使えば処理効率を向上することが可能ですが、割り込みはCPUが直接行ってくれる処理なので、OSが提供してくれるサービスを利用するよりすばやく処理の切り替えを行うことができます。
※プリエンプティブ・・・優先度の高いタスクが優先度の低いタスクの実行権を奪い取ることができるという意味
PICは全てのシリーズが timer0 を持っており、timer0 のオーバーフローにより割り込みを発生させることができます。まずはtimer0のオーバーフロー割り込みを利用した簡単なサンプルプログラムを示します。
ただ単にLEDの光を右から左に流すだけのプログラムですが、delay関数を使わずに、タイマ割り込みで1msを作っています。
「ボタン操作によるラジコンサーボの制御(悪い例)」のサンプルプログラム(pio_3.c)は delay関数を使っていましたが、これをタイマ割り込みで作り直してみました。
基本的なつくりはほとんど同じで、時間管理の部分を作り変えてあります。このプログラムは、これで完璧ということではなくて、delay関数で15ms待っている pio_3.c よりはだいぶましになっているという程度のものです。
では、処理効率がどれくらいましになったのか、処理のタイミングを図を見ながら検証してみましょう。
ラジコンサーボの制御周期はだいたい15〜20ms程度なので、pio_3.cではON時間の分だけ処理が伸びることを考慮して 15ms のdelayを使ってOFFの時間を稼いでいます。サーボの出力角度が45°のときON時間が1900usなので、ON時間の上限を2000us(2ms)、イベント受付や角度-ON時間変換等で300us(0.3ms)として、サーボのON時間の処理にかかる時間は最大でも2.5msと見積もりました。シミュレータデバッガでボタンとLEDの処理時間を計測してみたところ、それぞれ36us、8us程度だったので、1msもかからないことがわかります。
以上の見積もりからサンプルプログラム pio_3.c の処理タイミングを図に表すと下図のようになります。delay関数で時間がたつのを待っている間は別の処理ができないわけですが、その時間が如何に長いかがわかりますね。
![]() |
| 図 delay関数を用いて15ms待ちを行っている pio_3.c の処理タイミング |
続いて、このdelay待ちをtimer0割り込み+スケジューリングに改良したサンプルプログラム interrupt_1a.c の処理タイミングの例を下図に示します。最悪のケースを想定して、ほぼ同タイミングでサーボ、ボタン、LEDともに処理すべきタイミングになった場合を例にとりました。一応、処理に優先順位をつけて、プライオリティ(優先度)の高いものから処理するように作ってあります。(プリエンプティブではありません。)
![]() |
| 図 timer0割り込みによりスケジューリングを行った interrupt_1a.c の処理タイミング |
上の図を見ると、delay関数を使って15ms待っている場合と比べて、サーボの処理周期が正確な上、空き時間が沢山あって、もっと沢山の処理が可能なことが判ります。このやり方なら、サーボの制御周期を20msにすれば6個くらいまでは同時に駆動できそうです。
処理効率の点からみればだいぶ良くはなったのですが、まだ問題点が残っています。それは、ON時間をdelayで実現している点です。delay関数を使用している以上、この時間は他の処理ができません。また、これから先、通信割り込みなど他の割り込みが入ってくると、割り込み処理中はdelay のカウントが行われないため、delayでON時間が終わるのを待っている間に割り込み処理が入ってON時間が延びてしまう恐れがあります。 さらには、10usのdelayをforループでまわしているため、実際にはON時間が設定値より若干長めにでてしまうことを避けられません。
ではどうしたらdelayを使わず、ON時間正確に作ることができるでしょうか? 解決策はいろいろあると思いますので、考えてみてください。