一、数码管的显示原理
1.数码管的简介
数码管是一种半导体发光器件,其基本单元是发光二极管。 数码管也称 LED 数码管,不同行业人士对数码管的称呼不一样,其实都是同样的产品。数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要 显示的内容;按能显示多少个(8)可分为 1 位、 2 位、 3 位、 4 位、 5 位、 6 位、7 位等数码管。按发光二极管单元连接方式可分为共阳极数码管和共阴极 数码管。 共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数 码管,共阳数码管在应用时应将公共极 COM 接到+5V,当某一字段发光二极管的 阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就 不亮。 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数 码管,共阴数码管在应用时应将公共极 COM 接到地线 GND 上,当某一字段发光 二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相 应字段就不亮。 不同位数的数码管实物图如下所示:
2.数码管的显示原理
不管将几位数码管连在一起,数码管的显示原理都是一样的,都是靠点亮内部的发光二极管来发光,下面我们就来讲解一个数码管是如何亮起来的。数码管内部电路如下图所示

通过给a,b,c,d,e,f,g,dp各个脚加上不同的控制电压可以使不同的LED灯导通、发光,从而显示0~9各个数字和A,B,C,D,E,F各个字母,因此数码管可以用来显示二进制数、十进制数、十六进制数,如下图所示:

3.数码管类型、管码表
由于8个LED共有16个引脚,为了减少引脚,形成了共阳极(共正极)和共阴极(共负极)两种数码管,其特点如下表所示:
名称 | 图示 | 说明 |
共阴极数码管(典型的型号有CPS05011AR, SM420501K, SM620501, SM820501等) | (注意:3脚和8脚在数码管内部使连通的) | 引脚采用上、下派结构的数码管,其引脚的编号如图(b)所示。 内部将8个LED的负极连接在一起,接成一个公共端(COM端),这就形成了共阴极数码管。 点亮方法:给公共端加上低电平,将需要点亮的LED的引出脚加上高电平。 |
共阳极数码管(典型的型号有SM410561K, SM610501, SM810501等) | | 将8个LED的正极连接在一起,接成一个公共端(COM端),这就形成了共阳极数码管。 点亮方法:给公共端加上高电平,将需要点亮的LED的引出脚加上低电平即可 |
如上图所示结构的共阴极数码管表(具体的进制数需根据电路图去计算),共阴极的数码管,通1为高电平,即对应的数码管亮。
数字 | 十六进制数 | 二进制数 |
0 | 0x3f | 0011 1111 |
1 | 0x06 | 0000 0110 |
2 | 0x5b | 0101 1011 |
3 | 0x4f | 0100 1111 |
4 | 0x66 | 0110 0110 |
5 | 0x6d | 0110 1101 |
6 | 0x7d | 0111 1101 |
7 | 0x07 | 0000 0111 |
8 | 0x7f | 0111 1111 |
9 | 0x6f | 0110 1111 |
A | 0x77 | 0111 0111 |
B | 0x7c | 0111 1100 |
C | 0x39 | 0011 1001 |
D | 0x5e | 0101 1110 |
E | 0x79 | 0111 1001 |
F | 0x71 | 0111 0001 |
如上图所示结构的共阳极数码管表(具体的进制数需根据电路图去计算),共阳极的数码管,通0为低电平,即对应的数码管亮(即共阴极取反)。
数字 | 十六进制数 | 二进制数 |
0 | 0xC0 | 1100 0000 |
1 | 0cF9 | 1111 1001 |
2 | 0xA4 | 1010 0100 |
3 | 0xB0 | 1011 0000 |
4 | 0x99 | 1001 1001 |
5 | 0x92 | 1001 0010 |
6 | 0x82 | 1000 0010 |
7 | 0xf8 | 1111 1000 |
8 | 0x80 | 1000 0000 |
9 | 0x90 | 1001 0000 |
A | 0x88 | 1000 1000 |
B | 0x83 | 1000 0011 |
C | 0xc6 | 1100 0110 |
D | 0xa1 | 1010 0001 |
E | 0x86 | 1000 0110 |
F | 0x8e | 1000 1110 |
这些码段不需要去记住,需要时查资料即可,需知道的是为什么段码是这样的。编制段码的方法为:例如显示0,则数码管的a,b,c,d,e,f应点亮,若公共端为低电平,则a,b,c,d,e,f的引脚为高电平(a=b=c=d=e=f=1)。从高位到地位排列为hgfedcba=0011 1111,0011的十六进制为3,1111十六进制为f,因此编码为0x3f。
二、数码管的静态显示
1.数码管的静态显示电路
所谓静态显示,就是数码管的笔画点亮后,这些笔画一直处于点亮状态,而不是出于周期性点亮状态。如下图所示,用单片机P0端口驱动一个共阴极数码管:

2.数码管的静态显示示例
使用共阴极数码管,间隔0.5秒依次循环显示:1~9~0~.~A~F
#include<reg51.h>
char LED[] = {0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x3f,0x80,0x77,0x7C,0x39,0x5e,0x79,0x71},k;
void delay(){
int i,j;
for(i=500;i>0;i--)
for(j=120;j>0;j--);
}
void main(){
while(1){
for(k=0;k<17;k++){ //使用数组存储数字的信息,for循环依次将值赋值给P0口从而点亮相应的管灯
P0 = LED[k];
delay();
}
/* 基础方法,将每一个数字按顺序都写上
P0 = 0x06;delay(); //1
P0 = 0x5b;delay(); //2
P0 = 0x4f;delay(); //3
P0 = 0x66;delay(); //4
P0 = 0x6d;delay(); //5
P0 = 0x7d;delay(); //6
P0 = 0x07;delay(); //7
P0 = 0x7f;delay(); //8
P0 = 0x6f;delay(); //9
P0 = 0x3f;delay(); //0
P0 = 0x80;delay(); //.
P0 = 0x77;delay(); //A
P0 = 0x7C;delay(); //B
P0 = 0x39;delay(); //C
P0 = 0x5e;delay(); //D
P0 = 0x79;delay(); //E
P0 = 0x71;delay(); //F*/
}
}
三、数码管的动态显示
1.数码管动态显示原理
多位数码管依然可以静态显示,但是显示时要么只显示一位数码管,要么多位同时显示相同内容。当多位数码管应用于某一系统时,它们的“位选”是可独立控制的,而“段选”是连接在一起的,我们可以通过位选信号控制哪几个数码管亮,而在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的,因为它们的段选是连接在一起的,送入所有数码管的段选信号都是相同的,所以它们显示的数字必定一样,数码管的这种显示方法叫做静态显示。 而动态显示,就是利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据来实现的。比如在第一次选中第一位数码管时,给段选数据 0,下一次位选中第二位数码管时显示 1。为了在显示1的时候,0 不会消失(当然 实际上是消失了),必须在人肉眼观察不到的时间里再次点亮第一次点亮的 0。 而这时就需要记住,人的肉眼正常情况下只能分辨变化超过 24ms 间隔的运动。 也就是说,在下一次点亮 0 这个数字的时间差不得大于 24ms。这时就会发现, 数码管点亮是在向右或者向左一位一位点亮,形成了动态效果。如果把间隔时间改长就能直接展现这一现象。
2.数码管的动态显示电路
我的开发板上是连接了一个74H138芯片,进行数码管的位选。芯片结构如下图所示:
他是一种三通道输入、八通道输出译码器,A,B,C相当于二进制的三个位,可以产生2^3=8种结果,即利用此芯片,只需单片机上的三个引脚即可控制8个数码管的选择。比如输入是 101(A2,A1,A0),其对应的十进制数 是 5,所以 Y5 输出有效电平。
我的开发板上的数码管模块的电路如下所示:
结合上边的74H138芯片,可通过单片机的P0空控制每一个灯显示的数字,通过单片机的P22,P23,P24口控制选择第几个数码管。
3.数码管的动态显示示例
任务1:8个数码管,从左到右,肉眼能看见的显示3.1415926
#include<reg51.h>
sbit A1 = P2^2;
sbit A2 = P2^3;
sbit A3 = P2^4;
char LED[] = {0x3f,0x06,0x5b,0xcf,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0 1 2 3. 4 5 6 7 8 9
void delay(int h){ //延时函数
int i,j;
for(i=h;i>0;i--)
for(j=120;j>0;j--);
}
void main(){
while(1){
A1=0;A2=0;A3=0;P0 = LED[6];delay(1); //8管
A1=0;A2=1;A3=0;P0 = LED[9];delay(1); //6管
A1=1;A2=0;A3=0;P0 = LED[2];delay(1); //7管
A1=1;A2=1;A3=0;P0 = LED[5];delay(1); //5管
A1=0;A2=0;A3=1;P0 = LED[1];delay(1); //4管
A1=0;A2=1;A3=1;P0 = LED[1];delay(1); //2管
A1=1;A2=0;A3=1;P0 = LED[4];delay(1); //3管
A1=1;A2=1;A3=1;P0 = LED[3];delay(1); //1管
}
}