状態をカウントする方法について

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

状態をカウントする方法について

#1

投稿記事 by C素人 » 7年前

SWが全部で8個あります。
SWの状態に応じて、LEDが点灯するプログラムを作成しています。

SWの状態が0x00の時の状態をカウントし、
カウントした値(変数count)に応じて、0x01の時の動作を変更したいと考えています。

次のプログラムで試してみましたが、
当たり前ですが、0x00の状態に一度入ると、その間はループが続くので、カウントアップも繰り返されてしまいます。
その状態(0x00)に入ったら、1つだけカウントアップさせたいのですが、どのようにすれば良いのでしょうか?

コード:

while(1){
    char use_r = 0, use_g = 0, use_b = 0; /* 各関数を使うか */
    char is_valid = 1; /* 定義があるか */
	int count=0;
 
    sw = PORTA & 0xFF;
 
    switch(sw){
        
            case 0x00:
                use_r = 1;
                use_b = 1;
				count++;
                break;
 
            case 0x01:
				if(count==3){
                use_b = 1;
				}
				else{
				use_g = 1;
				}
				break;
 
            case 0x30:
                use_g = 1;
                use_b = 1;
                break;
 
        default:
            is_valid = 0;   /* 定義が無かった */
            break;
    }
 
    /* 定義がある場合のみ処理する */
    if(is_valid) {
        if(prev_sw != sw) {
            Reset();        //初期化
            delay_ms(1);    //delay
        }
 
        if (use_r) LED_R();
        if (use_g) LED_G();
        if (use_b) LED_B();
    }
 
    prev_sw = sw;
}

maru_yoshi

Re: 状態をカウントする方法について

#2

投稿記事 by maru_yoshi » 7年前

13行目

コード:

count++;

コード:

if (prev_sw != sw)  count++;

あんどーなつ
記事: 171
登録日時: 7年前
連絡を取る:

Re: 状態をカウントする方法について

#3

投稿記事 by あんどーなつ » 7年前

オフトピック
質問とは関係ないのですが、
ソースコード中の「定義があるか」「定義が無かった」は、
「空き状態(空きステート)であるか」「空き状態」と書いたほうがわかりやすいと思います。

空きステートの反対は、「定義された状態」だと思うのですが、
この言葉は「空き状態」に比べるとピンとこない言葉です。

Cプログラマが思いつく、定義があるかというのは、以下のような場合に使うと思います。

コード:

#ifdef DEVICE_HAS_LEDR
  void RED_R() {
    PORTB |= 0x01;
  }
#endif

(略)

#ifdef DEVICE_HAS_LEDR // 定義があるか
  LED_R();
#endif

C素人

Re: 状態をカウントする方法について

#4

投稿記事 by C素人 » 7年前

maru_yoshi 様

回答ありがとうございました。
教えていただいた方法でカウントすることができました。

あんど~なっつ様
「定義」について、コメントありがとうございます。
勉強になります。

C素人

Re: 状態をカウントする方法について

#5

投稿記事 by C素人 » 7年前

度々すみません。

解決したと思っていたのですが、解決できていませんでした。
確認の際、17行目を count>=3としてしまっていました。

確認のため、ループの頭に、カウントが5000以上になったら、LEDを点灯するようにしてみました。

swの状態を0xFFから、0x00にして確認してみたところ、(これでカウント1回としているつもり)
5000回もいっていないのに、LEDが点灯してしまいます。

原因がまったくわからず困っています。


コード:

[while(1){
  if(count>=5000){
	LED=1;
    }

    char use_r = 0, use_g = 0, use_b = 0; /* 各関数を使うか */
    char is_valid = 1; /* 定義があるか */
    int count=0;
 
    sw = PORTA & 0xFF;
 
    switch(sw){
        
            case 0x00:
                use_r = 1;
                use_b = 1;
                count++;
                break;
 
            case 0x01:
                if(count==3){
                use_b = 1;
                }
                else{
                use_g = 1;
                }
                break;
 
            case 0x30:
                use_g = 1;
                use_b = 1;
                break;
 
        default:
            is_valid = 0;   /* 定義が無かった */
            break;
    }
 
    /* 定義がある場合のみ処理する */
    if(is_valid) {
        if(prev_sw != sw) {
            Reset();        //初期化
            delay_ms(1);    //delay
        }
 
        if (use_r) LED_R();
        if (use_g) LED_G();
        if (use_b) LED_B();
    }
 
    prev_sw = sw;
}

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

Re: 状態をカウントする方法について

#6

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

count>=5000で参照しているcountの定義はどうなっていますか?
(このコンパイラではどうかわかりませんが、普通のC言語ではこれより下にあるループ内のcountは認識しないはずです)

LEDの初期値はどうなっていますか?初期化していますか?また、本当に1で点灯、0で消灯ですか?
LED_*()関数(やReset()関数?)内でLEDを点灯させているのを見ているのではないですか?

そもそも、カウントするのに使う変数を毎ループ初期化していると、カウントはできないでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

C素人

Re: 状態をカウントする方法について

#7

投稿記事 by C素人 » 7年前

みけCAT様

回答ありがとうございます。
おっしゃられる通り、カウントする変数を毎回初期化していました。

LEDに関しましても、もう1度確認し、初期化するようにしました。
また、1で点灯、0で消灯となることも確認しました。

この状態で、私が動作確認したプログラムを添付させていただきます。
このコードでも、
swの状態を0xFFから、0x00にして確認してみたところ、(これでカウント1回としているつもり)
5000回もいっていないのに、LEDが点灯してしまいます。

なにかおかしなことをしてしまっているのでしょうか。

コード:

	int count=0;

	while(1){
    LED=0;    

  if(count>=5000){
    LED=1;
    }
 
    char use_r = 0, use_g = 0, use_b = 0; /* 各関数を使うか */
    char is_valid = 1; /* 定義があるか */

 
    sw = PORTA & 0xFF;
 
    switch(sw){
        
            case 0x00:
                use_r = 1;
                use_b = 1;
                if (prev_sw != sw)  count++;
                break;
 
            case 0x01:
                if(count==3){
                use_b = 1;
                }
                else{
                use_g = 1;
                }
                break;
 
            case 0x30:
                use_g = 1;
                use_b = 1;
                break;
 
        default:
            is_valid = 0;   /* 定義が無かった */
            break;
    }
 
    /* 定義がある場合のみ処理する */
    if(is_valid) {
        if(prev_sw != sw) {
            Reset();        //初期化
            delay_ms(1);    //delay
        }
 
        if (use_r) LED_R();
        if (use_g) LED_G();
        if (use_b) LED_B();
    }
 
    prev_sw = sw;
}

閉鎖

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