みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語のプログラムについて(LEDの点灯)

C言語初心者です.
LEDを以下のように点灯させるプログラムをC言語でつくりたいのですが,わからなくて困っており,質問させていただきました.
「LEDを1秒間点灯させ,0.5秒間消灯させ,また1秒間点灯させ,次は0.6秒間消灯させるというように消灯時間を0.1秒おきに増やしていき,消灯時間を1.5秒間まで増やした後,今度は0.1秒おきに消灯時間を減らしていき,消灯時間を0.5秒間まで減らし,これを繰り返す.」(分かりづらくてすみません…)
というようなプログラムはどのようにつくればいいでしょうか?

ちなみに1秒おきに点灯,消灯を繰り返すプログラムは,メイン関数を
void main()
{
while(1){
LED1_ON();
delay_us(1000);
LED1_OFF();
delay_us(1000);
}
}
とすることで出来ました.

投稿日時 - 2010-11-15 11:38:59

QNo.6320737

困ってます

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

まず、

while(1)
{
LED1_ON();delay_ms(1000);
LED1_OFF();delay_ms(1000);
}

で、本当に、1秒間隔になっていることを確認してください。
次は、

int timeON = 1000;
int timeOFF = 1000;

while(1)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}

を確認してください。
このあと、timfOFF を 500 とか、800 とかに変更して確認してみてください。
ここでおかしいようだと、delay_ms() の設計ミスで、異なる引数で呼ばれたときにおかしな事が起きているというのが考えられます。

ここまで大丈夫だと、タイミングがおかしいのは気のせいのような気がしますが。

あとは、


LED1_ON();delay_ms(500);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(600);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(700);
LED1_OFF();delay_ms(1000);

LED1_ON();delay_ms(800);
LED1_OFF();delay_ms(1000);

という感じで、点滅の感覚をつかむと良いかもしれません。

投稿日時 - 2010-11-15 16:17:59

お礼

while(1)
{
LED1_ON();delay_ms(1000);
LED1_OFF();delay_ms(1000);
}
これはちゃんと1秒間隔で大丈夫でしたが

int timeON = 1000;
int timeOFF = 1000;

while(1)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}
これで明らかにはやくなりました.
そしてtimeOFFの数値を変更しても点滅の間隔は変わりませんでした.
ありがとうございました

投稿日時 - 2010-11-15 17:26:48

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

ほとんどできている気がしますけど。
あとは、ループで繰り返すだけで。

ちょっと書き換えると、1秒ON/1秒OFF のプログラムは、
void main()
{
while(1){
LED1_ON(); delay_us(1000);
LED1_OFF(); delay_us(1000);
}
}

です。(改行を変更しただけです。これで、1秒(1000ms)ON している様子がわかると思います)
これを、timeON ms と timeOFF ms の点滅に書き換えると、

void main()
{
int timeON = 1000;
int timeOFF = 1000;

while(1){
LED1_ON(); delay_us(timeON);
LED1_OFF(); delay_us(timeOFF);
}
}

消灯時間を毎回増やすには、

whie(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
点滅の処理
}
}

というループにするだけです。
この後減らすところも安直に作るなら、

whie(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
点滅の処理
}

for (timeOFF = 1400; timeOFF >= 600; timeOFF -= 100)
{
点滅の処理
}

}

で、その動きにはなると思います(確認してませんけど)
これは、「点滅の処理」という同じものが2カ所出てくるので、関数なんかにして独立させると良いかと思います。


そのほかにもバリエーションがあって、

int timeOFFList[] =
{500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500,
1400, 1300, 1200, 1100, 1000, 900, 800, 700, 600, -1};

で、

int i = 0;
while(1)
{
timeOFF = timeOFFList[i];
点滅の処理
i++;
if (timeOFFList[i] < 0) i = 0;
}

とか。
これは、データを作る(というか書く)のが面倒ですが、制御の流れ自体は追いかけやすいと思います。

あと、増減をひとつのループでやってみる場合、考え方として、「増減」の制御はややこしいです。
ただ、増減というのは、途中で折り返すと[増加」なのですね。

while(1)
{
for(timeOFFWork = 500; timeOFFWork < 2400; timeOFFWork += 100)
{
timeOFF = (timeOFFWork > 1500) ? 3000 - timeOFFWork : timeOFFWork;
点滅の処理
}
}

という制御もありかなと思います。
こちらは、あとから、「なに? この意味不明な計算」となりかねない気はします。

投稿日時 - 2010-11-15 12:55:47

補足

順を追ったわかりやすい説明有難うございます!
void main(void)
{

int timeON = 1000;
int timeOFF;

while(1)
{
for (timeOFF = 500; timeOFF <= 1500; timeOFF += 100)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}

for (timeOFF = 1400; timeOFF >= 600; timeOFF -= 100)
{
LED1_ON();delay_ms(timeON);
LED1_OFF();delay_ms(timeOFF);
}
}

}
というプログラムでやったところ点滅は一定間隔ではなさそうなのですが,あきらかに1秒よりも早い早さで点滅をしてしまいました.どこかミスがあるのでしょうか; ちなみに間違って書いてしまったのですがusではなくmsでした.

投稿日時 - 2010-11-15 15:43:31

あなたにオススメの質問