PICには、特定のハードウエア的な要因が発生すると、指定した処理関数を実行させる機能:「割り込みといいます」が利用できます。たとえば、PIC
が シリアル通信で getc() 関数で受信処理をj実行すると、getc() は受信文字を取得するまで処理を続け、この間に他の処理はできなくなります。
通常のプログラムでは、この間に、必要な信号が到着しても、無視してしまします。しかし、「割り込み」を利用すると、このような場合でも、対応ができます。
PICでは、「PB0」端子に割り込み機能が付加されています。この端子に接続された信号が変化すると、割り込みを起こすことができます。割り込みが起こると、現在実行中のプログラムを中断して、割り込み処理関数を呼び出します。割り込み処理は、次のように記述します。
#割り込み要因
<割り込み処理関数>
PB0 端子による割り込み要因は int_ext になります。この処理関数を、ext_isr() とします。割り込み信号を、計数信号とし、計数値を
count に記録する場合、次のような処理になります。
#int_ext
void ext_isr()
{
count++;
}
これで、main() で始まる関数が、別の処理をしていても、PB0 に計数信号が入ると、count を増やすことが可能です。
割り込みを利用するには、予め、割り込みを許可する「手続き」が必要です。許可には、割り込み要因別の許可と「割り込みそのもの」の許可が必要です。
PBOの信号変化による割り込みを許可するには
enable_interrupts(int_ext);
を呼び出します。また、割り込み機能を有効にするには
enable_interrupts(GLOBAL);
が必要です。また、
disnable_interrupts(GLOBAL);
で、「割り込み」そのものを一時的に停止できます。
RS232Cで文字を受信したとき割り込みむ関数は,#int_rda で定義します。
#int_rda
void rda_isr(){
}
押しボタンのような機械式のスイッチは、オンやオフをするとき、安定するまで数回の断続を繰り返す場合があります、この現象をチャタリングといいます。ボタンを押した回数を調べるとき、チャタリングは誤動作の原因となります。
チャタリングは、スイッチからの信号にコンデンサを付加してハード的に防止したり、一定時間反応しないよう、ソフト的に対応することもできます。詳細はこちらを参照してください。
RS232Cの実験回路に加えて、スイッチをRB0に接続します。これで、スイッチを押すと、割り込みを起こすことができます。
割り込みは、信号の変化(立ち上がり、または、下がり)で発生します。上がりか下がりかは設定することができます。スイッチは RB0 に接続します。他の端子では、int_ext
型の割り込みは生成できません。
RB1、RB2、にRS232Cの信号、RB0をスイッチを接続します。PS232Cを接続したPCではハイパーターミナルを起動しておきます。実行すると、ハイパーターミナル画面は
ボタンの押し下げ回数を表示します。ボタンを押すと、count の値が増えるため、画面の count 数が増加します。
また、ハイパーターミナルでキーを入力すると、その文字が画面に表示されます。キー入力とボタン押し下げ処理が割り込みで同時に処理できます。
#include <16f873.h> #fuses INTRC_IO,NOWDT,NOLVP,NOMCLR//内部クロック、WDT,LVPなし #use delay(CLOCK=4000000) //クロック4MHz //#fuses HS,NOWDT,NOLVP,put,brownout //PIC873の場合クロック、WDT,LVPなし //#use delay(CLOCK=20000000)//PIC873の場合 #use RS232(BAUD=9600,xmit=PIN_C6,rcv=PIN_C7)//PIC648の場合 //#use RS232(BAUD=9600,xmit=PIN_B2,rcv=PIN_B1)//PIC873の場合 int count; char ch; #int_ext void ext_isr() { count++; printf("\n\r count%d:",count); delay_ms(100); } #int_rda void rda_isr(){ ch=getchar(); putchar(ch); } void main(){ set_tris_b(0x0b); count=0; printf("\n\rHello"); enable_interrupts(int_ext); enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); while(1){ } }
RS232Cを利用する場合、
#use RS232(BAUD=9600,xmit=PIN_B2,rcv=PIN_B1)//PIC873の場合
で、送受信の端子を指定しますが、指定した端子が、ハードウエアで用意された端子と異なる場合、CSCコンパイラは自動的にソフトウエアのみによる RS232C
の送受信関数を組み込みます。この場合、割り込みは利用できません。割り込みを利用しないで、getchar() などの受信関数を呼び出すと、文字を受信するまで戻りません。他の処理はできなくなりますから注意してください。また、getchar()を呼び出す前に送られた文字は受信できません。
ext_isr() の delay_ms(100); を削除して、チャタリングの有無を確認して下さい。