1回だけ処理した後に繰り返し処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
素人

1回だけ処理した後に繰り返し処理

#1

投稿記事 by 素人 » 10年前

[ハード構成]
SW1 (ONで0がマイコンに入力)
SW2 (ONで0がマイコンに入力)
LED1
LED2


[プログラムの内容]
SW1 & SW2 OFFの状態: LED1とLED2が点灯・消灯を繰り返す


この状態から、
SW1がON
又は
SW2がON
又は
SW1,SW2の両方がON した場合には、次の処理を行う。(1つでもSWがONしたら、次の★★処理をずっと繰り返す。



★★★★★★★★★★★★★★★★★★★★★★★★★★
SW1,SW2の両方がONのとき、LED1,2の両方が点灯
SW1がONのとき、LED1点灯
SW2がONのとき、LED2点灯
SW1,SW2の両方がOFFのときは、直前のSWの状態の動作
★★★★★★★★★★★★★★★★★★★★★★★★★★


[不具合の内容]
LED1とLED2が点灯・消灯を繰り返す状態から、いずれかのSWをONしても、LED1とLED2が点灯・消灯を繰り返す状態が続いてしまう。

コード:

	int st,left,right;
	int sw;
	st=0;
	left=0;
	right=0;
	delay_ms(100);
 while(1){	  
	sw = PORTB & 0x03;
	while (sw=0x03) {
				LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 1;
				delay_ms(100);
				LATCbits.LATC4 = 0;
				LATCbits.LATC5 = 0;
				delay_ms(100);
				LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 1;
	}
	switch(sw){
		case 0:	LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 1;
				st=1;
				left=0;
				right=0;
				delay_ms(30);
				break;
		case 1:	LATCbits.LATC4 = 0;
				LATCbits.LATC5 = 1;
				left=1;
				delay_ms(30);
				break;
		case 2:	LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 0;
				right=1;
				delay_ms(30);
				break;
		case 3:	
			if (st==1){
				LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 1;
				st=0;
			}
			else if (left==1){
				LATCbits.LATC4 = 0;
				LATCbits.LATC5 = 1;
				left=0;
			}
			else if (right==1){
				LATCbits.LATC4 = 1;
				LATCbits.LATC5 = 0;
				right=0;
			}	
				break;
		default:break;
		}	
    }
}


アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 1回だけ処理した後に繰り返し処理

#2

投稿記事 by usao » 10年前

前回
http://dixq.net/forum/viewtopic.php?f=3&t=17125
と同様に,9行目は
× while (sw=0x03)  →  ○ while( sw==0x03 )
ではないでしょうか.



上記のミスを直したとしても,
このwhileループ(9~18行目)の中では,変数swの値が変わる処理が存在しないので
一度このループ内に入ったら抜ける方法が無いように思います.

素人

Re: 1回だけ処理した後に繰り返し処理

#3

投稿記事 by 素人 » 10年前

usao様 ありがとうございます。

////////////////////////////////////////////////////////////////////////////
このwhileループ(9~18行目)の中では,変数swの値が変わる処理が存在しないので
一度このループ内に入ったら抜ける方法が無いように思います.
////////////////////////////////////////////////////////////////////////////

ご指摘の通りで、このループに入った状態から抜けられません。
私の理解が間違えていると思うのですが、
white(sw==0x03) 内の処理は、
swが0x03の状態の間はずっとこのwhile文内の処理を行う。と理解しています。
そのため、swの状態が変化すれば、このwhile文を抜けられると考えていました。

この考えが間違えているのでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 1回だけ処理した後に繰り返し処理

#4

投稿記事 by みけCAT » 10年前

素人 さんが書きました:私の理解が間違えていると思うのですが、
white(sw==0x03) 内の処理は、
swが0x03の状態の間はずっとこのwhile文内の処理を行う。と理解しています。
そのため、swの状態が変化すれば、このwhile文を抜けられると考えていました。

この考えが間違えているのでしょうか。
この考えは間違っていないでしょう。
しかし、ループの中にswを更新する処理が無いため、割り込みなどでループの外からループの条件で参照しているswを更新しないとループから抜けられません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 1回だけ処理した後に繰り返し処理

#5

投稿記事 by usao » 10年前

>swの状態が変化すれば、このwhile文を抜けられると考えていました。

それは全くそのとおりなのですが,抜けるための条件である
>swの状態が変化
する処理が存在していないので,結果としてwhileループから抜けません,ということです.

(提示されたコードでは,変数swの値が変化しそうな処理は 8行目の
 > sw = PORTB & 0x03;
 しか見当たりません.
 9行目~18行目の部分をループでぐるぐると処理している間は
 8行目の処理は行われませんので,swの値はずっと0x03のままです.)



あまり関係ないですが,↓のように,
最初の処理(SWが2つともOFFである間の処理)と,SWがONされた後の処理 とを
分けて書いた方がわかりやすいかもしれませんね.

コード:

...

sw = PORTB & 0x03;  //スイッチの初期状態を取得

//(1)両SWが共にOFFの間はLED1とLED2が点灯・消灯を繰り返す
while( sw == 0x03 )
{
   ... (点灯・消灯のための処理)

   sw = PORTB & 0x03;  //スイッチの状態を取得
}

//(2)少なくともひとつのSWがONにされて以降の処理
while( 1 )
{
  switch( sw )
  {//スイッチの状態に合わせてLED点灯
    case 0:
      ...
      break;

    case 1:
      ...
      break;

    case 2:
      ...
      break;

    default:
      //※両SWがOFFのときには特になにもしなくてもよい気がする
      break;
  }

  sw = PORTB & 0x03;  //スイッチの状態を取得
}

素人

Re: 1回だけ処理した後に繰り返し処理

#6

投稿記事 by 素人 » 10年前

usao様

ありがとうございました。勉強になります。

閉鎖

“C言語何でも質問掲示板” へ戻る