如图所示:
从上图可看出,一位数码管的引脚是 10 个,显示一个 8 字需要 7 个小段, 另外还有一个小数点,所以其内部一共有 8 个小的发光二极管,最后还有一个 公共端,多数生产商为了封装统一,单位数码管都封装 10 个引脚,其中第 3 和 第 8 引脚是连接在一起的。而它们的公共端又可分为共阳极和共阴极,图中间 为共阳极内部原理图,右图为共阴极内部原理图。
对共阴极数码来说,其 8 个发光二极管的阴极在数码管内部全部连接在一起, 所以称“共阴”,而它们的阳极是独立的,通常在设计电路时一般把阴极接地。 当我们给数码管的任意一个阳极加一个高电平时,对应的这个发光二极管就点亮 了。如果想要显示出一个 8 字,并且把右下角的小数点也点亮的话,可以给 8 个阳极全部送高电平,如果想让它显示出一个 0 字,那么我们可以除了给第“g, dp” 这两位送低电平外,其余引脚全部都送高电平,这样它就显示出 0 字了。
如果使用共阴数码管,需要注意增加单片机 IO 口驱动电流,因为共阴数码 管是要靠单片机 IO 口输出电流来点亮的,但单片机 I/O 口难以输出稳定的、如 此大的电流,所以数码管与单片机连接时需要加驱动电路,可以用上拉电阻的方 法或使用专门的数码管驱动芯片,比如 74HC573、74HC245 等,其输出电流较大, 电路接口简单。
共阳极数码管其内部 8 个发光二极管的所有阳极全部连接在一起,电路连接 时,公共端接高电平,因此我们要点亮哪个发光管二极管就需要给阴极送低电平, 此时显示数字的编码与共阴极编码是相反的关系,数码管内部发光二极管点亮 时,也需要 5mA 以上的电流,而且电流不可过大,否则会烧坏发光二极管。因此 不仅要防止数码管电流过大,同时要防止流经数码管的电流集中到单片机时电流 132 不能过大,否则会损坏主芯片。
一般共阳极数码管更为常用,为什么呢? 这是因为数码管的非公共端往往 接在 IC 芯片的 I/O 上,而 IC 芯片的驱动能力往往是比较小的,如果采用共阴极 数码管,它的驱动端在非公共端, 就有可能受限于 IC 芯片输出电流不够而显示 昏暗,要外加上拉电阻或者是增加三极管加大驱动能力。但是 IC 芯片的灌电流, 即输入电流范围比较大。所以使用共阳极数码管的好处是:将驱动数码管的工作 交到公共端(一般接驱动电源),加大驱动电源的功率自然要比加大 IC 芯片 I/O 口的驱动电流简单许多。另一方面,这样也能减轻主芯片的负担。
我们开发板上使用的数码管是 2 个四位一体的共阴极数码管(即 8 个 LED 的阳极全部并联一起引出,阴极分别引出如 A、 B…DP),本章实验也是在该 数码管上实现单个的静态显示。如果要让共阴数码管显示数字 0,即对应的段 ABCDEF 要点亮即给它高电平,其他的段熄灭即给它低电平。其他的数字显示方 式一样,这里就不多说。下面给出共阴和共阳数码管的 0-F 段码数据表,如下所 示:
LED 数码管显示器工作方式有两种:静态显示方式和动态显示方式。静态显 示的特点是每个数码管的段选必须接一个 8 位数据线来保持显示的字形码。当送 入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优 点是占用 CPU 时间少,显示便于监测和控制。缺点是硬件电路比较复杂,成本较 高,比如使用 4 个静态数码管,那么就得 32 个 IO 来控制,这对 51 单片机来说 是无法承受的,正因为如此才会有后面章节动态数码实验的讲解。 动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制是哪一 位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位 数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人 的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所 以在选择限流电阻时应略小于静态显示电路中的。
#include "reg52.h"
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
typedef unsigned char u8;//对系统默认数据类型重新命名
//定义共阴极数码管显示0-f的段码数据
u8 date_list[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*
*静态数码管实验,通过LED8数码管来实现
*/
void main(){
SMG_A_DP_PORT=date_list[0];//数码管显示为0
while(1);
}
在实际 应用中通常都需要显示多位数值,如果采用静态数码管显示就不够好,因此就需 要采用另外一种显示方式,即数码管动态显示。开发板上板载 2 个四位一体的共 阴数码管,所要实现的功能是:控制动态数码管从左至右显示数字 0-7。
多位数码管,即两个或两个以上单个数码管并列集中在一起形成一体的数码 管。当多位一体时,它们内部的公共端是独立的,而负责显示什么数字的段线 (a-dp)全部是连接在一起的,独立的公共端可以控制多位一体中的哪一位数码 管点亮,而连接在一起的段线可以控制这个能点亮数码管亮什么数字,通常我们 把公共端叫做“位选线”,连接在一起的段线叫做“段选线”,有了这两个线后, 通过单片机及外部驱动电路就可以控制任意的数码管显示任意的数字了。 一般一位数码管有 10 个引脚, 二位数码管也是 10 个引脚, 四位数码管是 12 个引脚,关于具体的引脚及段、位标号大家可以查询相关资料,最简单的办 法就是用数字万用表测量,若没有数字万用表也可用 5V 直流电源串接 1k 电阻后 测量,将测量结果记录,通过统计便可绘制出引脚标号。多位数码管有许多是按 一定要求设计的,引脚不完全按照一般规则设定,所以需要在使用时查找手册。
多位数码管依然可以静态显示,但是显示时要么只显示一位数码管,要么多 位同时显示相同内容。当多位数码管应用于某一系统时,它们的“位选”是可独 立控制的,而“段选”是连接在一起的,我们可以通过位选信号控制哪几个数码 管亮,而在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的,因 为它们的段选是连接在一起的,送入所有数码管的段选信号都是相同的,所以它 们显示的数字必定一样,数码管的这种显示方法叫做静态显示。
而动态显示,就是利用减少段选线,分开位选线,利用位选线不同时选择通 140 断,改变段选数据来实现的。比如在第一次选中第一位数码管时,给段选数据 0, 下一次位选中第二位数码管时显示 1。为了在显示 1 的时候,0 不会消失(当然 实际上是消失了),必须在人肉眼观察不到的时间里再次点亮第一次点亮的 0。 而这时就需要记住,人的肉眼正常情况下只能分辨变化超过 24ms 间隔的运动。 也就是说,在下一次点亮 0 这个数字的时间差不得大于 24ms。这时就会发现, 数码管点亮是在向右或者向左一位一位点亮,形成了动态效果。如果把间隔时间 改长就能直接展现这一现象。
数码管动态显示的应用非常多,所以大家一要认真学好数码管的动态显示方法。
通过前面内容的介绍我们知道,要使单片机能控制开发板上 2 位一体的共阴 数码管显示,仅靠单片机 IO 口来驱动是不行的,这里就需要增加外部驱动芯片, 开发板上使用的是 74HC245 芯片。2 个 4 位一体的共阴数码管的位选线有 8 根, 直接让单片机 IO 口控制是没有任何问题的,但考虑到 51 单片机 IO 口资源的限 制,通常我们会使用一种 IO 扩展芯片,比如 74HC138、74HC164、74HC595 芯片 等,只需要很少的单片机 IO 口就可以扩展出 8 个控制口,通过级联方式甚至可 扩展出更多的控制口)。我们开 发板上使用的是 74HC138 译码器芯片,只需单片机 3 个 IO 口就可以实现 8 个位 选管脚的控制,节省了芯片的 IO 资源。
74HC245 是一种三态输出、八路信号收发器,主要应用于大屏显示,以及其 它的消费类电子产品中增加驱动。
(1)主要特性
①采用 CMOS 工艺
②宽电压工作范围:3.0V-5.0V
③双向三态输出
④八线双向收发器
⑤封装形式:SOP20、SOP20-2、TSSOP20、DIP20
(2)管脚功能定义
从上面的管脚功能定义说明及真值表可以知道该芯片使用方法很简单,给 OE 使能管脚低电平,DIR 管脚为高电平传输方向是 A->B 输出,DIR 为低电平传输方 向是 B->A,至于输出高电平还是输出低电平取决于输入端的状态,如果输入为 低电平,输出即为低;输入为高电平,输出即为高。如果 OE 使能管脚为高电平, 不论 DIR 管脚是高还是低,输出是高组态。 通常我们使用 74HC245 芯片用作驱动只会让其在一个方向输出,即 DIR 管脚 为高电平,传输方向是 A->B
74HC138D 是一种三通道输入、八通道输出译码器,主要应用于消费类电子产 品。
(1)主要特性
①采用 CMOS 工艺
②低功耗
③工作电压:3.0V-5.0V
④封装形式:SOP16
从上面的管脚功能定义说明及真值表可以知道该芯片使用方法很简单,给 E1、E2 使能管脚低电平,E3 管脚为高电平,至于哪个管脚输出有效电平(低电 平),要看 A0,A1,A2 输入管脚的电平状态。如果 A0,A1,A2 都为低电平,则 Y0 输出有效电平(低电平),其他管脚均输出高电平。如果 A0 为高电平,A1, A2 都为低电平,则 Y1 输出有效电平(低电平),其他管脚均输出高电平。其他 143 几种输出大家可以对照真值表查看。如果 E1、E2 使能管脚任意一个为高电平或 者 E3 为低电平,不论输入是什么,输出都为高电平。
这里给大家总结一个方法:A0、A1、A2 输入就相当于 3 位 2 进制数,A0 是 低位,A1 是次高位,A2 是高位。而 Y0-Y7 具体哪一个输出有效电平,就看输入 二进制对应的十进制数值。比如输入是 101(A2,A1,A0),其对应的十进制数 是 5,所以 Y5 输出有效电平(低电平)。
/*
#include "reg52.h"
#define SMG_A_DP_PORT P0 //使用宏定义数码管段码口
typedef unsigned char u8;//对系统默认数据类型重新命名
//定义共阴极数码管显示0-f的段码数据
u8 date_list[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
*/
/*
*静态数码管实验,通过LED8数码管来实现
*/
/*
void main(){
SMG_A_DP_PORT=date_list[0];//数码管显示为0
while(1);
}*/
/*
*动态数码管实验,通过延时小于24ms,使得人眼观察是多位数码管一起亮
*/
#include "reg52.h"
typedef unsigned int u16;//对系统默认数据类型重新命名
typedef unsigned char u8;
#define SMG_A_DP_PORT P0 //使用宏定义数码管段选管脚
//定义数码管位选管脚
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
//定义共阴极数码管显示0-f的段码数据
u8 date_list[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay_10us(u16 ten_us){//进行延时操作当ten_us = 1时延时10us
while(ten_us--);
}
void smg_display(void){//数码管显示
u8 i;
//先进行位选操作,在进行段选操作
for(i = 0;i<8;i++){
switch(i){//位选
case 0: LSA = 1;LSB = 1;LSC = 1;break;//从左到右第一个数码管
case 1: LSA = 0;LSB = 1;LSC = 1;break;//第二个数码管
case 2: LSA = 1;LSB = 0;LSC = 1;break;//第三个
case 3: LSA = 0;LSB = 0;LSC = 1;break;//第四个
case 4: LSA = 1;LSB = 1;LSC = 0;break;//第五个
case 5: LSA = 0;LSB = 1;LSC = 0;break;//第六个
case 6: LSA = 1;LSB = 0;LSC = 0;break;//第七个
case 7: LSA = 0;LSB = 0;LSC = 0;break;//第八个
}
//位选完之后,传入段选数据
SMG_A_DP_PORT = date_list[i];
delay_10us(100);//延时一段时间,使得显示稳定
SMG_A_DP_PORT = 0x00;//在将段选口清零即消隐(消除之前的显示)
}
}
void main(){
while(1){
smg_display();
}
}
main.c 文件内代码非常少也很简单,首先将 51 单片机的头文件包含进来,然后定义 38 译码器的控制引脚,并将共阴数码管 0-F 段码数据使用数组定义好。主函数功能也很简单,直接进入 while 循环,在循环体内执行 smg_display()数码管动态显示函数。该函数是根据动态数码管显示原理所编写,即选中所要显示的那位数码管,然后发送在该位数码管上所要显示的段码数据,延时一定时间后在将段选口清零即消隐(消除之前的显示),如此循环 8 次即可实现 8 位数码管显示。在动态显示中,要注意延时时间,只要保证在人肉眼所能感觉时间之内即可,让我们看到所要显示的内容就像是同时显示一样。如果时间过长或者过短都可能会影响数码管的显示效果,大家可以在例程基础上试着修改延时时间观察效果。
结束!!!