【割込み処理とは?】
PICROSでの割込み処理は特別なものになっているわけではありません。
通常の割込み処理と全く同じ作り方で構いません。
通常と異なるのは、実際のデータ処理などをタスクで別に実行させるような
場合で、このような場合には、割込み処理でデータを準備してから、
Trigger_Task関数を実行して、この処理タスクを起動します。
【割込み処理の作り方】
CCS社のCコンパイラでは割込み処理は下記のようにして作成します。
#INT_XXX
XXX_isr( )
{
割込み処理プログラム
}
これで自動的に割込みベクタから、XXXで指定したモジュールの割り込みを
認識してレジスタ類を退避してから、上記処理プログラムにジャンプして来ます。
そして上記割込み処理を実行したあと、レジスタ類を復帰させてから、RETFIE
命令で割込みを許可しながら割込みが入ったところへ戻ります。
ここまで自動的にコンパイラが処理してくれますので、ユーザーは割込み処理
としてすることだけを記述すれば済むようになっています。
ここでXXXに相当するものには下記が用意されています。
#INT_AD : A/D変換完了
#INT_ADOF : A/D変換タイムアウト
#INT_CCP1 : CCP1のキャプチャ、コンペア割込み
#INT_CCP2 : CCP2のキャプチャ、コンペア割り込み
#INT_COMP : コンパレータ一致
#INT_EEPROM : EEPROMの書き込み完了割込み
#INT_EXT : 外部割込み
#INT_PSP : パラレルスレーブポート割込み
#INT_RB : PORTB RB4-7の変化割込み
#INT_RDA : USART受信完了割込み
#INT_RTCC: タイマ0カウントアップ割込み
#INT_SSP : SPIかI2Cの割り込み
#INT_TBE : USART送信レディ割込み
#INT_TIMERx: タイマX タイムアップ割込み
PICROSに対応させた割込み処理は、単に、上記割込みプログラムの中に
Trigger_Task(task)関数を追加するだけになります。
【実際の割込み処理例】
では実際のPICROSに対応させた割込み処理の例を説明します。
まず例題1は、タイマ1の割込み処理です。ここでは単純にタイマ1がカウントアップ
したらタスク6を起動するだけの処理を実行しています。
これだけの処理プログラムで割込み処理が完結します。レジスタの退避、復旧は
<例題1>
////////////////////////////////
// Timer 1 Interrupt Routine
////////////////////////////////
#INT_TIMER1
timer1_isr()
{
Trigger_Task(task6);
}
Cコンパイラが自動的に付加してくれますし、割込みフラグのクリアも付加してくれ
ます。実に簡単に記述できてしまいます。
例題2はUSARTの受信割込み処理の例です。
ここではパソコンからの文字列を受信するという処理を実行しています。つまり
割込みが入ったら、受信データを読み込みデータバッファに格納し、改行コード
だったら、そこで終了とみなして文字列に0x00を追加してからタスク7を起動して
います。 もし文字列バッファをオーバーしたら最初から入れなおします。
<例題2>このようにタスクにデータを渡したい時には、バッファを使いますが、このバッファは
///////////////////////////////////////////////
// USART Receive interrupt Routine
///////////////////////////////////////////////
#INT_RDA
void usart_isr()
{
static int colum = 0;
rcv_data[colum] = getc(); //1文字入力
if (rcv_data[colum] == 0x0D) //改行コードか
{
rcv_data[colum+1] = 0; //0x00を追加
colum = 0; //for next receive
Trigger_Task(task7); //タスク7を起動
}
else
{
colum++; //バッファインデックス+1
if (colum > 18) //バッファ一杯か?
colum = 0;
}
}
共通変数領域としてSTATIC変数で初期化の時に確保しておく必要があります。
そうしないと異なるタスク間でのデータの受け渡しが出来なくなってしまいます。