PICによる7セグLED3桁制御
度々こちらに、お世話になっております。
今回は、3桁のLEDを1から999までカウント表示する
プログラムに取組んでいるところ希望通りに、動いてはくれません。
このソースのベースは2桁(1から99までカウントUP)の
ソースコードを変更して、3桁表示させる様にしてみました。
コード概要はtimer0割込みで3.2msのインターバルタイムの間、
LEDをダイナミック点灯させ、timer1では、100msのインターバルタイムを
10回繰り返し(1秒毎に)counterを1プラスしてLEDの表示を1ずつ
増して999まで表示後、また000から繰返すと言う単純な動作のものです。
main()関数内はtimer0とtimer1の割込み設定及び
割込み開始、許可を繰返すだけです。
問題の#timer0,#timer1割込み関数処理部分における実行結果は、
000から111と言う具合に3桁が同時にカウント表示されてしまい、
しかも繰り上がる時間は1秒毎の筈が、100秒毎になります。
このコードはCCS-Cコンパイラに準拠していて、
標準Cとは多少異なる部分があり解りにくいと思いますが
どうかどなた様からも検証より不具合コード部分のご指摘と修正を
頂くことが出来るなら、大変光栄に思います。
そこで、PICにおけるconfigu部分は省き、概ねのコードを記します。
////
1:static long int number;
2:static int counter;
3:int const LED_SEG[11]= {0x7E,0xCC,...略}
4:#int_timer0
5:void isr()
{
6:static int a,b,c = 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;
15:output_b(LED_SEG[a]);
16:output_high(PIN_C0);//1桁目ON
17:output_b(LED_SEG[b]);
18:output_high(PIN_C1);//2桁目ON
19:output_b(LED_SEG[c]);
20:output_high(PIN_C2);//3桁目ON
}
21:#int_timer1
22:void isr()
{
23:set_timer1(0x0BDC);//100ms再設定
24:counter++;
25:if(counter>9)//10回か
{
26:counter = 0;
27:number++;
}
28:if(number>1000)
{
29:number = 0;
}
}
30:void main()
{
略
31:setup_timer0(3.2msセット)
32:setup_timer1(100msセット)
33:timer0割り込み許可
34:timer1割り込み許可
35:GLOBAL全体割り込み許可
36:while(1){}
}
////
以上宜しくお願いいたします。
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つだけという状態になってます。
評価に則したご回答頂き、ありがとうございます。
もう一度ハード側をじっくり眺めていると、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桁同じ表示のまま。
と言う風に自分で解釈一応溜飲が下がり完結となりましたので
ありがとうございました。
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 ;
}
}
この回答への補足
早速、検証からご回答いただきましてありがとうございました。
switch文の判定により、caseの処理へと、ご教示のとおりコード追加修正後
評価いたしましたところ、見事に、1ずつカウントアップ動作表示する事ができ
大変感激いたしております。
該当のcase定数式をプラス1して、break;よりルーチンを抜けることで、
1回の割込み毎に1桁のみ表示すると言う風に、理解いたしました。
ところが、問題は解決したのですが、自分の中ではまだ、疑問が残ります。
ご回答の中で、修正前のコードでは、なぜ割込みを抜けると3桁目の表示
のままになるのでしょうか?timer1では1秒間のcounterアップよりnumberを1つ変化させるまで、
timer0の方は3.2ms毎の割込み処理を繰返し続けていて、その後number値の変化に対して桁表示式より
各桁を表示するものと考えるのですが、100秒毎に3桁同時に1つインクリメントとなる事に、
どうしても、合点がいきません!
ここのところが、疑問のままでは、これでスッキリとはいきません。
どうか、愚な私に、お許しの範囲で結構ですので、もう少しアドバイス頂けるなら幸いに思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 コードを書いたのですが上手く実行出来なかったです。どこが間違ってますか? 【作成したいもの】 1 2022/05/04 11:36
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Microsoft ASP LEDで電光掲示板に「A B C D E」と表示したいのですが・・・ 1 2023/07/04 07:37
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- その他(プログラミング・Web制作) micropythonコード 修正 1 2023/06/13 17:22
- 工学 LED、CdS(受光素子)、ディジタル IC(組み合わせ回路,順序回路)、タイマーICの技術を組み合 1 2022/12/23 10:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スーパーのレジで並んでいたら...
-
アセンブラのタイマー割り込み
-
AKI-H8/3048Fでのタイマ割り込み
-
一定時間操作がなかったら、と...
-
[コンピュータアーキテクチャ]...
-
ショッピング
-
割り込み処理から引数を取得す...
-
割り込み処理のシミュレート
-
電車で待機列の割り込みについ...
-
Macターミナルで実行中のプログ...
-
VBAの配列サイズとメモリに関して
-
緯度、経度の 10進法と 60進法...
-
C言語で、メモリを解放しないで...
-
なんかC言語でプログラム書いて...
-
タスクマネージャーのプロセス...
-
バックグラウンドのプロセスの...
-
TCP/IP通信時のサーバーからの受信
-
プログラミング ソースコード
-
Excel-VBAのmsgBox()の不思議
-
Webプログラムってネイティブア...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
インバウンドで迷惑している人...
-
pic 複数の割り込み関数 切り分...
-
スーパーのレジで並んでいたら...
-
ショッピング
-
Excelでタイマーの一時停止する...
-
電車で待機列の割り込みについ...
-
CPUの処理量を減らすコーデ...
-
C言語でPICマイコン開発
-
【組込み】割り込み中のstatic...
-
Amazonfireタブレットにわから...
-
マイコン C言語 割り込み処理...
-
USB機器からのデータ受信による...
-
一定時間操作がなかったら、と...
-
VB.net 割り込みの禁止
-
ウォッチドッグタイマ(WDT)の...
-
電車乗車時、並んでいるのに割...
-
USJでの割り込み
-
VB6でSendKeyを利用したTab移動...
-
PICでのプログラムによるチャタ...
-
割り込み中に例外異常
おすすめ情報