ここではアノードコモン型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);
}
}
}