■割り込み処理■

■割り込み処理とは■

通常のプログラムの動作中,緊急に処理しなければならなかったり,ある時間までに処理を終えなければならなかったりすることがある.このような処理を記述する目的で割り込み処理がある.割り込み処理は,CPUのハードウェア機能として実現され,通常のプログラムの実行を強制的に中断し,別のプログラム処理を割り込ませることができる. 割り込みした処理が終了した後は,何もなかったかのように元のプログラムをそのまま続行する.

■割り込み処理の種類■

割り込み処理は,ソフトウェア割り込みとハードウェア割り込みに分けられる.

ソフトウェア割込みは,特定の機械語命令を実行したときに,番号で指定された割込みを発生させる.ハードウェア割込みの場合には,タイマーや,外部信号などハードウェアとして用意されている外部要因によって,特定の割込み処理 が発生する.

■割込み処理の動作■

割込みが発生すると,自動的にレジスタがスタック上に退避され,割込み処理が開始される.機械語のiret命令を実行すると,レジスタ内容を復帰してから元の処理に戻る.

■NC30での割り込み処理記述■

ひとつの割込み処理用に,ひとつの関数を用意することになる.割込み要因が発生すると,対応する割込み関数が自動的に割込み処理される.割込み関数の場合には,返値を返すことや,引数を受け取ることができないため,次のプロトタイプに従う必要がある.

void 割込み関数名(void); //関数プロトタイプ

C言語のプログラムとしては,次のように記述することになる.

#pragma INTERRUPT 割込み関数名 //この関数が割り込み関数であることを示す
void 割込み関数名(void); //通常の関数プロトタイプ

void 割込み関数名(void)  //通常どおりの関数本体,ただし返値なし,引数なし
{
  /*

  割込み処理の部分

  通常のプログラムと同様に書く.
    ただし大域変数やポートアクセスする際には,整合性に注意.
  また,return文は書かないこと.

  */
}

この割込み関数は,割込みベクタテーブルに登録しておく必要がある.割込みベクタテーブルは,「sect30.inc」に記述されており,初期状態では 「dummy_int」関数が登録されている.これを「_割込み関数名(先頭の_に注意)」に変更する必要がある.先頭の「_」は,C言語のプログラムを機械語に翻訳する際に自動的に付加されるマークである.ライブラリとリンクする段階で,C言語の関数とライブラリ内の機械語で直接かかれたルーチンと区別するために使用される.

■この実験での利用例■

本実験では,この割り込み処理を光センサのための800Hzパルスの出力のために利用する.モータの制御のためのタイマーAOだけでなく,タイマーA1を使って800Hzの時間間隔を用意することになる.このように調べなければいけないタイマーが2つあるため,そのままではプログラムがとても複雑になってしまう.そこで,片一方の方のタイマー機能に対しては割り込み処理を利用する.タイマーA1が時間を知らせるときに,割り込みを発生させるようにしておき,割り込み処理内部でパルス出力をさせることにする.そうすると,mainの中ではタイマーA0だけを考えてプログラムすればよいことになり,タイマーA1については完全に無視することができるようになる.