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

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

解決済みの質問

LEDの点灯(C言語,PIC)

PICを用いてLEDを点滅させます.
#INT_RTCC
rtcc_pulse()
{
counter++;
if(counter == t){
counter = 0;
LED1_ON();
delay_ms(10);
}
else{
LED1_OFF();
}
この関数のtの値を変調させ,OFFの時間を徐々に増やしていき,それを繰り返したいのですが,やり方がわからず困ってます.
tはfor(t=52;t<=152;t+=10)のように増やしていきたいです.

投稿日時 - 2010-11-22 10:36:37

QNo.6335892

暇なときに回答ください

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

> クロック周波数を20Mhzに指定しており,152カウントするのに約1秒かかります.

ということは,約 6.6 ms 毎にタイマ割り込みがかかるということですね。

rtcc_pulse 関数内の delay_ms(10); は要りません。
10 ms も休んでいたら,次の割り込みが来てしまいます。

counter == t の時に,LED1_ON() していますが,
次に割り込みがかかったとき(約 6.6 ms 後)には,LED1_OFF() が呼ばれるので,
点灯しているようには見えないでしょう。

ON -> OFF のタイミングも時間をカウントして決めてやる必要があります。


# タイマや,割り込みの使用にこだわらないなら,ANo.2 にあるように,
# メインループ内で,点灯して,待つ,消灯して,待つ,を繰り返すのが簡単でしょう。

投稿日時 - 2010-11-24 19:43:17

お礼

delay_ms(10);消したら上手く行きました!
本当に有難うございました

投稿日時 - 2010-11-25 10:25:35

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

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

回答(4)

割り込みハンドラのようですが、どういうタイミングで呼ばれるか分かっていますか?

投稿日時 - 2010-11-23 01:36:07

お礼

回答ありがとうございます.クロック周波数を20Mhzに指定しており,152カウントするのに約1秒かかります.

投稿日時 - 2010-11-24 11:36:24

ANo.2

プログラムが不完全なのでなんともコメントが難しいです。
関数の定義だと思いますが、どのように動作させたいのでしょうか。
LED1_ONの意味もいまいち分かりません。

とりあえず、私ならの場合です

/*dutyでOFFの時間をコントロールする*/
int led_pulse(int duty){

 int i,count_max=100; /*一周期の長さをcount_maxで制御*/
 int state=1; /*状態を制御、0でOFF,1でONと仮定する*/

 i=0;
 while( i < count_max){
  if( i == duty ) state=0;
   /*適当なスリープ処理が必要*/
   i++;
  }
 }

 return(0);

}

大事な部分はこれでOKで、あとの部分は適当にお好みでやってください。
あくまで推測で書きました。

投稿日時 - 2010-11-22 21:57:48

お礼

回答有難うございます.全プログラムは以下のようになります.ほぼ初心者で参考書の例を見ながらやっているものでいらない,至らない部分なども多々あると思いますが;
#include<16F877a.h>
#fuses HS, NOWDT, NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=20000000) //クロックMHzの指定
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7)

/// 機能
void LED1_ON();

unsigned long counter;
unsigned long t;

///割り込み処理関数
#INT_RTCC
rtcc_pulse()
{
counter++;
if(counter == t){
counter = 0;
LED1_ON();
delay_ms(10);
if (t < 152) {
t += 10;
} else {
t = 52;
}
}
else{
LED1_OFF();
}
}
}
///メイン関数
void main(void)
{
setup_adc_ports(NO_ANALOGS);
set_tris_a(0x10);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
counter = 0;
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(1){
}
}

/// LED 1ON/OFF
void LED1_ON(){
output_low(PIN_E0);
}
void LED1_OFF(){
output_high(PIN_E0);
}
ちなみにこのプログラムだとLEDは光りません.
if (t < 152) {
t += 10;
} else {
t = 52;
}
}
の部分を消して,tに152を代入すると1秒周期で点滅します.

投稿日時 - 2010-11-24 11:34:03

ANo.1

例えば……tが152になったら52に戻って循環するという場合

#INT_RTCC
rtcc_pulse()
{
counter++;
if(counter == t){
counter = 0;
LED1_ON();
delay_ms(10);
if (t < 152) {
t += 10;
} else {
t = 52;
}
}
else{
LED1_OFF();
}

投稿日時 - 2010-11-22 10:45:57

お礼

回答ありがとうございます.
回答していただいたプログラムですとなぜか全くLEDが光りません.
また,
if (t < 152) {
t += 10;
} else {
t = 52;
}
の部分を単純にt=52と変えて,一定に点滅させようとしてもなぜか止まってしまいます.
しかしtの値に直接52を書いたり,宣言文のところでlong t = 52とする分にはちゃんと一定には点滅します.謎です;

投稿日時 - 2010-11-22 13:07:19

あなたにオススメの質問