2013年5月15日水曜日

PIC C18 割り込み遅延

  • Microchip C18 (Version 3.4.5)
  • PIC18F2321
  • クロックは 20MHz
  • 外部入力割り込み INT0(RB0) の立ち下がりエッジ
  • 割り込みは 31kHz 周期
  • 割り込みをカウントし、580発目で RA3ポートに L を出力
  • Hに戻すのは、590発目
という条件で、出力までの時間(遅延+処理)のテストをした。
  • 4usくらいで反応する
  • 0.2us( 4x1/20MHz )のゆらぎが発生する(完全同期は不可)
ところが、プログラムを書き換えたりしているうちに、応答時間が 12us と遅くなってしまった。
(波形上)(青波形が割り込み入力)

設定を変えてみたり、ネットで探ってみたが解決できず困った。Disassembly Listing View を追うと ISR に入るまでずいぶんとステップが入っている。

答えはC コンパイラ ユーザーズガイド(日本語版有り)にちゃんとあった。ISR に入るまでコンテキストの退避がすべての項目で実行されている模様。

最初は何も記述せず済んでいたのだが、nosave=XXX を書き加えないとならないハメになっようだ。

#pragma interrupt isr nosave=xxx,yyy,zzz

とISRセクション宣言部分に記述する。
WREG,BSR,STATUS 以外を nosave と記述した場合、8us に。 ISR からカウント関数呼び出しせず直接記述し直すと 4us となって、最もシンプルな形の応答時間(波形下)に戻った。

ISR: 割り込みサービスルーチンの事
ポートに出力するまでの 4us は、短縮の余地が残っている

【おまけ1】
ポートに出力するだけの一行しかない関数(名前をつけてわかりやすくしたいため)でも、CALL命令で正直にコンパイルされるため、かなりステップがかさむ事が分かった。必要なら、#defineで見た目だけポートの名前を変えるなどした方がいいのかも。
【おまけ2】
テスト用の基板を使ってオシロで測定していたが、Debugger->SelectTool->MPLAB SIM を使っても割り込み処理の時間計測ができる事が分かった。画面上で、割り込み信号を与えることもできる。