• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PICによる7セグLED3桁制御)

PICによる7セグLED3桁制御

このQ&Aのポイント
  • PICによる7セグLED3桁制御のプログラムに問題があり、想定とは異なる動作となっている。タイマー割り込み処理の部分を修正するためのアドバイスを求めている。
  • 現在、PICによる7セグLED3桁制御のプログラムを作成しているが、期待通りに動作しない。timer0割込みとtimer1割込みの処理が問題の可能性がある。アドバイスをいただけないだろうか。
  • PICによる7セグLED3桁制御のプログラムで問題が発生している。timer0とtimer1の割込み処理部分が正しく動いていないようだ。修正案を教えてほしい。

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

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

回答1の者です。的はずれな回答をしてしまってすみません。 > なぜ割込みを抜けると3桁目の表示のままになるのでしょうか? 1桁目・2桁目を消灯させずに、3桁とも表示した状態にしてしまっているからです。 質問者さんのコードの実行結果を順を追って説明すると、 > 15:output_b(LED_SEG[a]); > 16:output_high(PIN_C0);//1桁目ON ここで、1桁目のLEDのみONになり、1桁目のLEDに、aが表示されます。 > 17:output_b(LED_SEG[b]); ここで、1桁目のLEDの表示内容がbに変わります。 > 18:output_high(PIN_C1);//2桁目ON ここで、2桁目もONになり、1桁目もONにしたままですから、1桁目と2桁目に、bが表示されます。 > 19:output_b(LED_SEG[c]); ここで、1桁目と2桁目の表示内容がcに変わります。 ここまで、15~19は、μ秒オーダで起こりますから、まず視認できません。 > 20:output_high(PIN_C2);//3桁目ON ここで、3桁目もONになり、1桁目・2桁目もONにしたままですから、1桁目・2桁目・3桁目、全てのLEDにcが表示されます。 以上で、割り込みルーチンが終わりますから、次の割り込みまでの3.2m秒間はこの状態が続きます。 以上のながれで、「3桁めの数字だけが全桁表示された」状態が続くことになります。 一方、回答2のコードでは、 割り込みルーチン冒頭で全桁をOFFにしたあと、状態に応じて「1つだけをONに」していますから、 割り込みを抜けた時点では、点灯しているLEDは1つだけという状態になってます。

kodoku
質問者

お礼

評価に則したご回答頂き、ありがとうございます。 もう一度ハード側をじっくり眺めていると、7セグLED3個は マイコン側とは8本線で3桁が共通線として接続されている事に、今更気づきました。 ここが今回の、ポイントでした。 3個がそれぞれ8本ずつ、独立してマイコンに接続されているのなら 1ルーチン内でも、それぞれ違う表示が同時に可能になりますが、 ダイナミック点灯方式では、1つの表示方法をONとOFFより瞬時に切り替えて それぞれの桁を使い分けるところが、ミソのはず。 考えではダイナミック方式になっていると思っていたのですが、 実際には3.2msの一瞬に最後行までを実行、ルーチンを抜ける時 PIN_C2(3桁目)値の信号が1桁目、2桁目へも反映させた状態でルーチンを抜ける。 ということで、1桁目と2桁目が9・9までは0・0・0表示のままで、桁上がりで 1・0・0になると1・1・1になる。したがって その間のカウント時間は100秒になる事が、理解できました。 つぎにPIN_C2が変化するまで100秒間は3桁同じ表示のまま。 と言う風に自分で解釈一応溜飲が下がり完結となりましたので ありがとうございました。

その他の回答 (2)

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.2

タイマー0の割り込みルーチンが駄目です。 このままでは一回の割り込みの中で1桁目、2桁目、3桁目の表示を行っていて、 割り込みから抜けると3桁目の表示のままになってしまいます。 下記のように一回の割り込みでは一桁だけ表示するようにしましょう。 コンパイルはしていないのでエラーが有るかもしれません。 なお、全角スペースを使用しているのでタブか半角スペースに修正してください。 4:#int_timer0 5:void isr() { 6:static int a,b,c = 0;     static int state=0 ; 7:int x; 8:out_low(PIN_C0); // LED 1桁目off 9:out_low(PIN_C1); // LED 2桁目0ff 10:out_low(PIN_C2);// LED 3桁目0ff 11:a = number % 10; 12:x = number/10; 13:b = x % 10; 14:c = x / 10;     switch( state ){     case 0 : state++ ; 15:output_b(LED_SEG[a]); 16:output_high(PIN_C0);//1桁目ON     break ;     case 1 : state++ ; 17:output_b(LED_SEG[b]); 18:output_high(PIN_C1);//2桁目ON     break ;     default : state=0 ; 19:output_b(LED_SEG[c]); 20:output_high(PIN_C2);//3桁目ON     break ;     } }

kodoku
質問者

補足

早速、検証からご回答いただきましてありがとうございました。 switch文の判定により、caseの処理へと、ご教示のとおりコード追加修正後 評価いたしましたところ、見事に、1ずつカウントアップ動作表示する事ができ 大変感激いたしております。 該当のcase定数式をプラス1して、break;よりルーチンを抜けることで、 1回の割込み毎に1桁のみ表示すると言う風に、理解いたしました。 ところが、問題は解決したのですが、自分の中ではまだ、疑問が残ります。 ご回答の中で、修正前のコードでは、なぜ割込みを抜けると3桁目の表示 のままになるのでしょうか?timer1では1秒間のcounterアップよりnumberを1つ変化させるまで、 timer0の方は3.2ms毎の割込み処理を繰返し続けていて、その後number値の変化に対して桁表示式より 各桁を表示するものと考えるのですが、100秒毎に3桁同時に1つインクリメントとなる事に、 どうしても、合点がいきません! ここのところが、疑問のままでは、これでスッキリとはいきません。 どうか、愚な私に、お許しの範囲で結構ですので、もう少しアドバイス頂けるなら幸いに思います。

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

ソフトウェア的には問題なさそうですが、ハードウェア側はどうなっていますか? 質問のような状況からすると、LEDが3桁ともC2で駆動されてるように見受けられます。

kodoku
質問者

お礼

お目に留めていただき、ご回答ありがとうござました。 ハードウェア的には、問題ない、とは言い切れませんが delay()関数を使った3桁表示テストでは、プログラムどおり 動作できましたので、ハードは問題ないのではと判断しています。 3桁同時表示の問題が今一つ解決出来ていません。

関連するQ&A