• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PICの割り込み機能)

PICの割り込み機能とは?プログラミングでの実装方法を教えてください。

このQ&Aのポイント
  • PIC16F84Aを使用して、C言語でプログラムを作成し、LEDの点灯・消灯を制御しています。
  • 割り込みを実装することで、RA1の入力によってLEDの点灯を5秒後に自動的に消灯させることができます。
  • 現在のプログラムは割り込みがうまく機能せず、5秒後に点灯してしまう問題があります。解決方法を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

>消えている状態でRA1に入力を入れたときなぜか5秒後に点灯してしまいます。 点灯するでしょうね。そういうプログラムになってますから。 >・RA1に入力があったときLEDが点灯しているなら5秒後にLEDを消灯。 >・RA0に入力があったときRB0につないであるLEDが消灯しているならLEDを点灯。 RA1に入力があり、5秒後にLEDを消灯した次の瞬間に、RA0に入力があったら「LEDが消灯しているのでLEDを点灯」する事になります。 こういう場合には、普通 ・入力ポートに変化があったら割り込みがかかる ・タイマーにより割り込みがかかる と言うハード構成にします。 セオリーは「メインでポートを監視する為の無限ループを組まない事」です。 つまり >どれもすべて動作を終えて、あとはwhile(1)で割り込みを待つだけ というプログラムにするのが常道なのです。 なので、ネットでさがすと、そういうプログラムばかり見付かる筈です。 以下のような作り方をしましょう。 グローバル変数は「直前のRA0の状態」と「秒カウンタ」と「LEDの状態」を用意します。 int 直前のRA0の状態; int 秒カウンタ; int LEDの状態; main() {  ハードの初期化;  直前のRA0の状態=0;  秒カウンタ=0;  LEDの状態=0;  割り込み許可;  while(1) {;} } void interrupt isr(void) {  if (直前のRA0の状態 != 今のRA0) {   直前のRA0の状態 = 今のRA0;   if (RA0==1) {    LED点灯;    LEDの状態=1;    秒カウンタ=0;//RA1の入力後の5秒間にRA0が変化したらチャラにする   } else {    LED消灯;    LEDの状態=0;    秒カウンタ=0;//RA1の入力後の5秒間にRA0が変化したらチャラにする  }  if (秒カウンタ==0) {//通常時   if ((LEDの状態==0) && (RA1==1)) {//消灯時はRA1は無視    秒カウンタ++;//5秒待ち状態に入る   }    } else {//5秒待ち状態に入っている時   秒カウンタ++;   if (秒カウンタ>=500) {//1ミリ秒×500=5秒    LED消灯;    LEDの状態=0;//LEDを消す    秒カウンタ=0;//5秒待ち状態から通常状態に戻る   }  }  割り込みを再許可する } 割り込み間隔を1ミリ秒にしているのは、チャタリング防止の意味も兼ねていて、エッジノイズやパルスなど、1ミリ秒より短い変化は拾いません。

shin55555
質問者

補足

お早いご回答ありがとうございます。 >セオリーは「メインでポートを監視する為の無限ループを組まない事」です。 >つまり >>どれもすべて動作を終えて、あとはwhile(1)で割り込みを待つだけ >というプログラムにするのが常道なのです。 そーだったんですか・・・・。 とりあえず、このプログラムの通りやってみました、が、 なかなかうまくいきません(汗 最初にRA0につながれているスイッチを押したらそのままLEDがつきっぱなしになっちゃって・・・。 スイッチを押している間消えています。 あと割り込みもうまくいかなかったです・・・。 なかなか消えてくれません。 とりあえずプログラムは #include "pic.h" int a; //直前のRA0の状態 int cnt; //秒カウンタ int LED; //LEDの状態 main() { /*初期化始まり  TRISA=0xFF;  TRISB=0x00;  PORTA=0x00;  PORTB=0x00;  a=0;  cnt=0;  LED=0; */初期化終わり  OPTION=0x87; //割り込みの設定  TMR0=0x00;  T0IF=0;  T0IE=1; //割り込み許可  GIE=1; //全体割り込み許可  while(1) {;} } void interrupt isr(void) {  if (a != RA0) {   a = RA0;   if (RA0==1) {    RB0=0;    LED=1;    cnt=0; //RA1の入力後の5秒間にRA0が変化したらチャラにする   } else {    RB0=1;    LED=0;    cnt=0; //RA1の入力後の5秒間にRA0が変化したらチャラにする   }  } //※1  if (cnt==0) { //通常時   if ((LED==1) && (RA1==1)) { //消灯時はRA1は無視    cnt++; //5秒待ち状態に入る   }  } else { //5秒待ち状態に入っている時   cnt++;   if (cnt>=500) { //1ミリ秒×500=5秒    RB0=1;    LED=0; //LEDを消す    cnt=0; //5秒待ち状態から通常状態に戻る   }  }  T0IE=1; //割り込みを再許可する  GIE=1; } ※1…カッコが1つ足りなかったのでおそらくここだと思います。 という感じになっています。

その他の回答 (1)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

訂正   if ((LEDの状態==0) && (RA1==1)) {//消灯時はRA1は無視 は   if ((LEDの状態==1) && (RA1==1)) {//消灯時はRA1は無視 の間違い

関連するQ&A