一、数码管简介
LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字
型的器件。管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极
管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要显示的内容;一
个数码管分成八段,分别由a、b、c、d、e、f、g、dp(dp是小数点)八个二极管组成,数码按发光
二极管单元连接方式可分为共阳极数码管和共阴极数码管。 STC89C52RC是共阴极。
![](https://img-blog.csdnimg.cn/3e77381172a54f31a0938933e45046bc.png)
![](https://img-blog.csdnimg.cn/ef2bed19eeee4bc188f8dde10ac4a3af.png)
共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码
管在应用时应将公共极 COM 接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点
亮,当某一字段的阴极为高电平时,相应字段就不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码
管在应用时应将公共极 COM 接到地线 GND 上,当某一字段发光 二极管的阳极为高电平时,相应
字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。
二、显示原理
![](https://img-blog.csdnimg.cn/e5e8aabdf55a480385cf10a264bd118c.png)
从上图可看出,一位数码管的引脚是 10 个,显示一个 8 字需要 7 个小段,另外还有一个小数
点,所以其内部一共有 8 个小的发光二极管,最后还有一个 公共端,多数生产商为了封装统一,
单位数码管都封装 10 个引脚,其中第 3 和 第 8 引脚是连接在一起的。
对于STC89C52来说采用的使共阴极,对共阴极数码来说,其 8 个发光二极管的阴极在数码
管内部全部连接在一起,所以称“共阴”,而它们的阳极是独立的,通常在设计电路时一般把阴极接
地。当给数码管的任意一个阳极加一个高电平时,对应的这个发光二极管就点亮 了。如果想要显
示出一个 8 字,并且把右下角的小数点也点亮的话,可以给 8 个阳极全部送高电平,如果想让它
显示出一个 0 字,那么可以除了给第“g, dp” 这两位送低电平外,其余引脚全部都送高电平,这样
它就显示出 0 字了。
STC89C52使用的数码管是 2 个四位一体的共阴极数码管(即 8 个 LED 的阳极全部并联一起
引出,阴极分别引出如 a, b...dp)。在使用时,需要程序选定使用哪几个数码管,这就是"位选",
位选选定数码管后再对选定的数码管每个小段进行操作,其操作与单个数码管的操作一致这就是
“段选”。
0x3F |
0x06 |
0x5B |
0x4F |
0x66 |
0x6d |
0 |
1 |
2 |
3 |
4 |
5 |
0x7D |
0x07 |
0x7F |
0x6F |
0x77 |
0x7C |
6 |
7 |
8 |
9 |
A |
B |
0x39 |
0x5E |
0x79 |
0x71 |
0x00 |
|
C |
D |
E |
F |
无显示 |
|
三、静态数码管显示
![](https://img-blog.csdnimg.cn/2dd92d5d63394254b1168bc50ededa26.png)
上图电路实际上是动态数码管电路,使用的是 2 个四位一体的共阴数码管组成,即 8 位数码
管的段选数据 a-dp 全部并联一起引出,每位数码管的位选即公共端引出。STC89C52开发板上没
有单个的静态数码管,但依然可以在动态数码管电路中使用其中一个来学习静态数码管显示。还需
要通过74HC138(38译码器)来进行位选。
#include <REGX52.H>
typedef unsigned char u8;
void main()
{
P2_2=0; /低位
P2_3=0;
P2_4=1; //100 --> Y4 --> LED5
P0=0x7D; //0111 1101 高位对高位,低位对低位 显示数字6
while(1)
{}
}
四、动态数码管显示
多位数码管,即两个或两个以上单个数码管并列集中在一起形成一体的数码 管。当多位一体
时,它们内部的公共端是独立的,而负责显示什么数字的段线 (a-dp)全部是连接在一起的,独
立的公共端可以控制多位一体中的哪一位数码管点亮,而连接在一起的段线可以控制这个能点亮
数码管亮什么数字,通常我们把公共端叫做“位选线”,连接在一起的段线叫做“段选线”,有了这两
个线后,通过单片机及外部驱动电路就可以控制任意的数码管显示任意的数字了。
动态显示,就是利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据
来实现的。比如在第一次选中第一位数码管时,给段选数据 0,下一次位选中第二位数码管时显示
1。为了在显示 1 的时候,0 不会消失(当然实际上是消失了),必须在人肉眼观察不到的时间里
再次点亮第一次点亮的 0。而这时就需要记住,人的肉眼正常情况下只能分辨变化超过 24ms 间隔
的运动。也就是说,在下一次点亮 0 这个数字的时间差不得大于 24ms。这时就会发现,数码管点
亮是在向右或者向左一位一位点亮,形成了动态效果。
通过前面内容的介绍知道,要使单片机能控制开发板上 2 位一体的共阴数码管显示,仅靠单
片机 IO 口来驱动是不行的,这里就需要增加外部驱动芯片,开发板上使用的是 74HC245 芯片。2
个 4 位一体的共阴数码管的位选线有 8 根,直接让单片机 IO 口控制是没有任何问题的,但考虑到
51 单片机 IO 口资源的限制,通常会使用一种 IO 扩展芯片,只需要很少的单片机 IO 口就可以扩
展出 8 个控制口,STC89C52
开发板上使用的是 74HC138 译码器芯片,只需单片机 3 个 IO 口就
可以实现 8 个位选管脚的控制,节省了芯片的 IO 资源。
74HC245芯片
74HC245 是一种三态输出、八路信号收发器,主要应用于大屏显示,以及其它的消费类电子产
品中增加驱动。
(1)主要特性:
①采用 CMOS 工艺
②宽电压工作范围:3.0V-5.0V
③双向三态输出
④八线双向收发器
⑤封装形式:SOP20、SOP20-2、TSSOP20、DIP20
(2)管脚功能定义
![](https://img-blog.csdnimg.cn/9e32b7098ff7410095d60f0578aabe05.png)
通过上图可以知道给 OE 使能管脚低电平(低电平有效),DIR 管脚为高电平传输方向是 A-
>B 输出,DIR 为低电平传输方向是 B->A,至于输出高电平还是输出低电平取决于输入端的状态,
如果输入为 低电平,输出即为低;输入为高电平,输出即为高。如果 OE 使能管脚为高电平,不
论 DIR 管脚是高还是低,输出是高组态。
通常使用 74HC245 芯片用作驱动只会让其在一个方向输出,即 DIR 管脚 为高电平,传输方
向是 A->B。
74HC138 --38译码器
(1)主要特性:
①采用 CMOS 工艺
②低功耗
③工作电压:3.0V-5.0V
④封装形式:SOP16
(2)管脚功能定义:
![](https://img-blog.csdnimg.cn/e1b140aebb684e55b9e34cae3d9cc106.png)
![](https://img-blog.csdnimg.cn/18eba3f02f064ad3b07f643993caf766.png)
![](https://img-blog.csdnimg.cn/c3619f6049ed483a8947f3aef120e6b7.png)
给 E1、E2 使能管脚低电平,E3 管脚为高电平,至于哪个管脚输出有效电平(低电 平),要
看 A0,A1,A2 输入管脚的电平状态。如果 A0,A1,A2 都为低电平,则 Y0 输出有效电平(低
电平),其他管脚均输出高电平。如果 A0 为高电平,A1, A2 都为低电平,则 Y1 输出有效电平
(低电平),其他管脚均输出高电平。
#include <REGX52.H>
typedef unsigned char u8;
u8 NiXietube[]={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,
0x77,0x7C,0x39,0x5E,0x79,
0x71,0x00};
void delay(u16 ten)
{
while(ten--);
}
void NiXie(u8 Location ,u8 num)
{
switch(Location)
{
case 1: P2_2=1;P2_3=1;P2_4=1;break; //111 --> Y7 -->LED8
case 2: P2_2=0;P2_3=1;P2_4=1;break; //110 --> Y6 -->LED7
case 3: P2_2=1;P2_3=0;P2_4=1;break; //101 --> Y5 -->LED6
case 4: P2_2=0;P2_3=0;P2_4=1;break; //100 --> Y4 -->LED5
case 5: P2_2=1;P2_3=1;P2_4=0;break; //011 --> Y3 -->LED4
case 6: P2_2=0;P2_3=1;P2_4=0;break; //010 --> Y2 -->LED3
case 7: P2_2=1;P2_3=0;P2_4=0;break; //001 --> Y1 -->LED2
case 8: P2_2=0;P2_3=0;P2_4=0;break; //000 --> Y0 -->LED1
}
P0=NiXietube[num];
delay(100);
P0=0x00; //消影
}
void main()
{
while(1)
{
NiXie(1,1);//显示1
delay(20);
NiXie(2,2);//显示2
delay(20);
NiXie(3,3);//显示3
delay(20);
}
}