ここではアノードコモン型4桁数字表示器を紹介します。別項では、カソードコマン型の3桁の数字表示器を紹介しましたが、同じ構成での4桁表示回路は入手が困難です。ここでは、アノードコモン型の4桁の数字、または、時刻表示用の数字表示器(TLR4115)を紹介します。
アノードコモン型は、1桁を表示する7個のLEDの+(アノード)側が共通になっている素子の意味です。
これは、アノードコモン型の4桁の表示素子です。左の a,..g に表示する値を設定(0で点灯)ます。d1,..,d4
が各桁の制御端子で、+側を接続します。右側は、小数点や時刻表示のため、時と分の間に
: を表示するための LED の接続です。
3,4 が : の表示、1,2,5,7 は少数点の位置に点灯します。1+、1-
は各LEDの+側と-側の端子です。6,7は右端に並んで点灯し、時刻表示のAM,PM
の表示にも利用できます。
アノードコモン型の素子の電力をオン/オフするには、PNP型トランジスタが必要です。E,C,B
の3端子で構成されることは同じですが、極性が逆になります。Eを+電源に接続し、Bを低電圧(グランド)にして、EからBに電流を流すと、EからCに電流が流れるようになります。
PNPのスイッチとLEDを接続すると、次のようになります。トランジスタのB端子に抵抗をつけ、グランド電位にすると
E-C間が導通し、LEDの+側に電源の+が接続されます。ここで、各LEDの-側を抵抗を通してグランド電位にすると、LEDが発光します。
各桁のトランジスタを順にオンにすることで、4桁の数字の動的点灯が可能になります。
ここでは、信号線を節約するため、シフトレジスタ 74164 を利用します。CKにパルスを入れると、A*B
(AとBの論理積)の値をQAに記憶し、同時に QB,QC、..は QA,QB の値を取り込みます。したがって、QA,QB,QC、..、QG
の値が1ビットシフトします。CLR端子は記憶をすべて0にする端子ですが、ここでは利用しませんから、+5V
に固定しておきます。これを怠ると、CLR へのノイズのため、ときどき(不定期)に記憶がクリアされてしまいます。
このシフトレジスタはバーLEDの表示に、こことは異なる方法で利用しています。
PICと数字表示の4桁の7素子表示を直接接続すると、最低でも7+4本の接続が必要です。そこでシフトレジスタを利用し、7素子のデータをあらかじめシフトレジスタに送りこんでから、桁に対応するトランジスタをオンにして点灯します。シフトレジスタとは、CK(クロック)とA(データ)の2本で接続可能です。この2本に、B1,B2を利用します。B3,B4,B5,B6で各トランジスタを制御します。PICのこの端子を0にすると、トランジスタがオンになり、LEDに+電圧が供給されます。
4桁の数字を順に表示するプログラム例を示します。segment_data[] は7素子に表示するパターンですが、0で点灯するため、先の例と異なりデータの 0,1
を反転しています。
int segment_data[]={0x81,0xF3,0x49,0x61,0x33,0x25,0x05,0xF1,0x01,0x31};
データは、関数 void output_sr(int data) で上位のビットから順にシフトレジスタに記憶します。7回のシフトでデータがシフトレジスタに点灯され、シフトレジスタのQGに、7素子表示器のgのデータが記録されます。bit_test(d,7)
は変数dの第7ビットの値を返す、関数です。
関数、void output_dgt(int dgt,int val) で、各表示桁を制御するポートの番号を設定します。dgt=0
の第一桁は B3ピンで制御します。
#fuses HS,NOWDT,NOLVP//DT,LVPなし #use delay(CLOCK=20000000) //クロック4MHz //PB2..PB1にシフトレジスタ //PB3,4,5,6に桁指定 //5mS単位で各桁を表示 //20回表示したら、表示する数値を更新する int ct;//数字の更新間隔 long val,valc;//表示する数字 int digit;//表示する桁 //表示パターン(上位7ビット) //int segment_data[]= {0x7E,0x0C,0xB6,0x9E,0xCC,0xDA,0xFA,0xE,0xFE,0xCE}; int segment_data[]={0x81,0xF3,0x49,0x61,0x33,0x25,0x05,0xF1,0x01,0x31}; long st[4]; void output_sr(int data){ int i; int d; d=data; for(i=0;i<7;i++){ output_bit(PIN_B2,bit_test(d,7)); output_bit(PIN_B1,1); output_bit(PiN_B1,0); d=d<<1; } } void output_dgt(int dgt,int val) { switch (dgt){ case 0 :output_bit(PIN_B3,val);break; case 1 :output_bit(PIN_B4,val);break; case 2 :output_bit(PIN_B5,val);break; case 3 :output_bit(PIN_B6,val); } } void main(){ output_bit(PiN_B1,0); digit=0; ct=20;//数字を更新する周期 valc=0;//表示する値 while(1){ ct --; if(ct == 0){//数字の更新 //itoa(val,10,st); val=valc; st[3]=val/1000; val -= st[3]*1000; st[2]=val/100; val -= st[2]*100; st[1]=val/10; st[0]=val%10; valc++; if(valc==10000) valc=0; ct=10; } for(digit=0;digit<4;digit++){ output_sr( segment_data[st[digit]]); output_dgt(digit,0); delay_ms (3); //表示期間(ミリ秒) output_dgt(digit,1); } } }