質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

1回答

1296閲覧

PICマイコン タイマ割込み ループ処理中

raspypy

総合スコア247

0グッド

0クリップ

投稿2019/08/23 00:55

##やりたいこと
PICマイコン(PIC16F18xx、XC8コンパイラ)を使用して、タイマ割込み処理を行っています。
割込みフラグを用意して、フラグの値によって、①と②の動作を切り替えた動作をしています。
①通常動作
3色のLEDを順番に点灯させています。
②タイマ割込み動作
SW(スイッチ)が押されたら、スイッチが押されている間は(ずっと)すべてのLEDを点灯させます。

##いまできていること
↓のコードで、割込みフラグによって、①と②の動作を切り替えるところまでできています。

##困っていること
①の動作の内容を変更したところ、タイマ割込み動作が行われなくなってしまいました。

変更した内容は、次の通りです。
①' 3色LEDの順番点灯を『100回繰り返し、100回に1度別の動作を行う。(ブザーを鳴らす)』
100回繰り返すところで、for文によるループ処理を入れています。

##コード
繰り返し処理の部分は、コメントアウトしてあります。

html

1 while(1){ 2 if(flag ==0){ 3 LED(); 4 } 5 else{ 6 SWON(); 7 flag=0; 8 } 9 } 10} 11 12//割り込み関数 13void interrupt isr(){ 14 GIE = 0; 15 if(TMR1IF == 1){ 16 //TMR1H = (63036 >>8); //タイマー1の初期化(65536-2500=63036); 17 //TMR1L = (63036 & 0x00ff); 18 flag=1; 19 TMR1IF = 0; //割り込みフラグを落とす 20 } 21 GIE = 1; 22} 23 24void LED(void) 25{ 26 int i; 27 //LED初期設定 28 LED1=0; 29 LED2=0; 30 LED3=0; 31 32 //カウントごとに行う処理(省略) 33 34 //for (i = 0; i < 100; i++) { 35 //SW = PORTCbits.RC3; 36 LED1=1; 37 __delay_ms(100); //100msec 38 LED1=0; 39 __delay_ms(100); //100msec 40 LED2=1; 41 __delay_ms(100); //100msec 42 LED2=0; 43 __delay_ms(100); //100msec 44 LED3=1; 45 __delay_ms(100); //100msec 46 LED3=0; 47 //} 48 49} 50 51void SWON(void) 52{ 53 while(SW == 0){ 54 LED1=1; 55 LED2=1; 56 LED3=1; 57 } 58 59}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

forを入れるとタイマ割り込みが行われなくなるんではなくて、タイマ割り込みでフラグがセットされても、そのforループが終わらないとつけっぱの処理が走らないだけ、です。

で、提示のコードではタイマ割り込みはなんの処理もしてませんね

C

1void interrupt isr(){ 2 if(TMR1IF == 1){ 3 flag=(SW!=0); 4 TMR1IF = 0; 5 } 6 GIE = 1; // この行いらないかも 7} 8 9 // メインループ 10 while(1){ 11 if(flag ==0){ 12 LED(); 13 } 14 else{ 15 LED1=1; 16 LED2=1; 17 LED3=1; 18 } 19 } 20

こんなもんですかねー

#割り込みルーチン省略しすぎたので修正

投稿2019/08/23 03:58

編集2019/08/23 04:09
y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raspypy

2019/08/23 07:14 編集

コードの提示ありがとうございました。 まず試してみた報告ですが、 ①電源投入後、LEDすべて点灯 ②SWを押すと、LEDが順番に点滅(SWを押さなければ、LEDすべて点灯のまま) ③一度SWを押した後は、再びSWを押すと、100ループ後にすべてのLEDが点灯しました。 実現させたい動作としては、SWを押したとき、100ループを待たずに、LEDをすべて点灯させたいです。 質問ですが、 flag=(SW!=0);  の理解として、次の理解で合っていますでしょうか? スイッチの状態が0と等しくなkれば(SWが押されていなければ)、flagに1を代入 スイッチの状態が0と等しければ(SWが押されていれば)、flagに0を代入 私の回路は、SWが押されたときに0となるので、 flag=(SW!=1); が正解でしょうか? ⇒ただし、これでも試してみましたが、電源ON後から、SWを教えても押さなくても、LEDが順番に点滅するだけでした。 もう1つ質問させてください。 flagのリセット(flag=0)がないのですが、なくても問題ないでしょうか?
y_waiwai

2019/08/23 11:08

SWが逆ならば、 flag=(SW==0); とすればいいです で、100回ループの途中でもつけっぱに移行したいならば、forの直後に if(flag!=0) break; をいれて、ループを中断させるようにすればいいです
y_waiwai

2019/08/23 11:10

> flagのリセット(flag=0)がないのですが、なくても問題ないでしょうか? この場合はそれは不要です
raspypy

2019/08/27 01:51

回答ありがとうございました。 1つ教えてください。 今回は、SWの状態に応じてフラグの値を設定し、フラグの値に応じた処理を実行しています。 フラグを宣言する際に、「volatile」を使用するようにアドバイスをいただきましたが、 なぜ、「volatile」を使用するのかが理解できていません。 教えていただけないでしょうか。
y_waiwai

2019/08/27 04:07

コンパイル時に、関数の中の変数の値は代入しない限り変更されない、という前提で最適化されます。 ふつーの変数の場合はこれで正しいのできちんと動きますが、割り込みで変更されるような変数の場合、それでは動作がおかしくなる場合があります volatile というのは、対象の変数の最適化はしないようにというにコンパイラの指示です これで、上記のような不具合は起こらなくなります
raspypy

2019/08/27 05:03

とても分かりやすい説明ありがとうございました。 助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問