【www.shanpow.com--数字歇后语】
(1) [数码管显示]第7课 数码管动态显示
第7课 数码管动态显示
在第6课里,我们讲到数码管的静态显示,利用静态显示法,通过控制位选和段选,可以让数任意几位数码管显示任意字符,但由于所有位数码管的相同的段选全部接在一起,所以只能同时显示相同的数字,例如8位同时显示8字,1、3、5位同时显示3字。但大家想一下,如果我们要让数码管同一时刻显示不同的数字,如图1所示的现象,用静态显示的方法就不能够实现,这里就只能用到动态显示的方法,今天这一节我们主要讲解数码管动态显示的原理的程序实现的方法。
图1 数码管同时显示123456
在讲解动态显示方法之前,我们先介绍在种数码管及单片机程序开发过程常用的方法-数组编码法。
1、数组编码
在跟数码管相关的程序中,可以对位进行编码,也可对段进行编码,这里我们以段编码进行讲解。通过第8课的程序我们知道,在位选确定后,要显示数字8时,P0=0x80,显示数字3时P0=0xb0,也就是0xb0,0x80分别可以表示数字3和8,按此方法,我们把在数码管上显示0-f,16个数字全部用16制度表示出来,这16个16进制数就称为数码管可显示0-f的相应的编码,如图2所示(注意共阳和共阴极数码管相应的编码有所不同,这里以实验板上共阳极的为例)。
图2 共阳极数码管编码
在编程中,编码的表示方法如下:
unsigned char code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e };
这里编码表示的方法与C语言中数组定义的方法基本一样。table是数组名,后面需加[],中括号中需加上数组中元素的个数,也可以不写。等号的右边用一个大括号将所有元素包含起来,里面的元素之间用“,”隔开,在大括号外用“;”结束。等号左边的unsigned char 是数据元素的数据类型,这里定义为无符号字符型,也就是元素的值范围只能是0-255之间。Code表示把这个数组定义为编码,这样定义的好处是其元素转化成二进文件后可能直接存储到程序存储器中,当然这里也可以不加code,但是这样编译后会将其直接存储到数据存储器中,要知道单片机中数据存储器的容量是非常有限的,定义为code后可节约单片机数据存储器的空间。
调用程序的方法如下,
P0=table[1];
这里表示将数组中的第2个元素(注意第一个是table[0])0xf9赋给P1口,
即P0=0xf9;也就是此时位被选通的数码管会显示数字2.
下面利用编码的方法让6个数码管以间隔1秒的时间循环显示0-f。相应程序如例1.
例1:6个数码管循环显示0-f
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;
sbit wei=P2^7;
uchar num;
unsigned char code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e };
void delay(uint);
void main()
{
wei=1;
P0=0xfe;
wei=0;
for(num=0;num<16;num++)
{
duan=1;
P0=table[num];
delay(150);
duan=0;
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=500;y>0;y--);
}
下载到实验板后实验现象如图3所示。
图3 6个数码管依次从0-f变化
2、数码管的动态显示
明白了数组编码后,现在我们正式介绍数码管的动态显示,为了更利于大家理解,我们先用前面介绍过的静态显示法写一个程序,功能为:让6个数码管间隔一秒依次显示1、2、3、4、5、6。程序如例2.
例2 数码管依次显示1、2、3、4、5、6
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;
sbit wei=P2^7;
uchar num;
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint);
void main()
{
while(1)
{
for(num=1;num<7;num++)
{
if(num==1)
{
wei=1;
P0=0xfe;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
else if(num==2)
{
wei=1;
P0=0xfd;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
else if(num==3)
{
wei=1;
P0=0xfb;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
else if(num==4)
{
wei=1;
P0=0xf7;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
else if(num==5)
{
wei=1;
P0=0xef;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
else if(num==6)
{
wei=1;
P0=0xdf;
wei=0;
duan=1;
P0=table[num];
delay(1000);
duan=0;
}
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
main函数内的意思num从1开始,一直加到6,然后不断的循环 (程序为for(num=1;num<7;num++),当num=1时,先打开第一位数码管,再让第一位数码管显示1(程序P0=table[num],即P0=table[1]),然后进行1s的延时(程序为delay(1000);)。紧接着当num=2时,打开第二位数码管,并让其显示2,延时1s……,一直到num=6时,打开第六位数码管,并让其显示6,延时1s,再重复前的的程序。这个我们就可以在实验板上看到数码管从第一位开始依次以1s的时间间隔依次显示123456.
下面的程序下载到实验板现象如图4所示。
图4数码管依次显示123456
现在我们把延时程序缩短(注意上面是延时1s,依次100ms 10ms 1ms ….一直到10us,然后把每次改后的程序下载到实验板,.当短到10us时,可看到如下现象:
也就是此时我们看到的现象是6个数码管在同一时刻按位依次显示123456,可能大家马上要提出疑问了,在上面不是说过利用静态的写法不是实现不了这种效果吗?这里就是数码管的动态显示。
所谓动态显示,就是依次向每位位数码管同时送出字形码和相应的位选,位与位之间利用延时程序进行延时,当延时程序非常短时,由于发光管的余辉和人眼视觉暂留作用,此时我们的人眼就分辨不出位与位之间有延时存在,此时就感觉各位数码管同时都在显示,这样我们实现在静态不能实现的功能。
(2) [数码管显示]第6课 数码管静态显示
第6课 数码管静态显示
1、数码管显示原理
数码管是单片机应用系统中常用的一种显示器件,由于其价格低廉、操作简单,而被广泛的应用于各种数字显示系统中,常见的数码管如图1所示。
根据外观的不同,数码管又为分1位数码管、2位数码管、3位数码管、四位数码管等种类,如图2所示。
但不论是几位一体的数码管,其显示原理都是一样的,都是靠内部发光二极管发光来进行显示的。下面我们以1位数码管为例介绍其显示原理。
1、数码管显示的原理
数码管内部的电路如图3所示,
图3 数码管内部电路
图3中,显示一个完整的8字,需要7个小段,外加一个小数点,共8段,分别称为a段、b段、c段、d段、e段、f段、g段、dp段,每段内部都集成了一个发光二极管,此时要想让数码管显示数字,我们只需要让相对应的发光二极管发光就可以,例如要想让此数码管显示数字是1,只需要让b、c段的数码管发光,而其它段的数码管熄灭就可以了。
上图中,每个发光二极管的阳极全部引出,分别为a、b、c、d、e、f、g、dp,共8个引脚,而把所有发光二极管的阴极全部接到一起引出一个引脚w,此时我们把a、b、c、d、e、f、g、dp引脚称为数码管的段选引脚,简称段选;而把w称为位选引脚,简称位选。通过单片机让数码管显示数字,就是通过编写程序让数码管内部相应的数码管发光。
数码管根据内部接法的不同又可分为共阴极数码管和共阳极数码管两种,上图中,数码管所有的发光二极管的阴极接在一起,而阳极单独引出,我们称此数码管为共阴极数码管,而还有一种接法是把阳极接在一起,而阴单独引出,这种数码管则称之为共阳极数码管,具体在写程序时应考虑到的是哪一种数码管,共阳极数码管如图4所示。
图4 共阳极数码管
这里需要注意的是,在驱动数码管进行显示时,数码管内部的发光二极管要正常工作大概需要5mA的电流,而单片机的I/O口通常不能提供如些大的电流,此时需要上位电阻或者专用的驱动芯片,如7HHC573等,实验板上即采用的后者,后面会具体讲到。
因为实验板上的数码管相应引脚在和单片机相连时用到了锁存器,这里介绍一下锁存器相关的一些知识。
锁存器(Latch)是一种对脉冲电平敏感的存储单元,它们可以在特定输入脉冲电平作用下改变和保持状态,所谓锁存,就是把信号暂存以维持某种电平状态。实验板上所用到的为74HC573,下面对其进行介绍。电路
74HC573为一种数字芯片,按其封装的不同,分为直插和贴片的两种,如图6和图7所示,
图6 直插式锁存器, 图7 贴片式锁存器,
下面先介绍下74HC573的各个引脚功能和真值表,如图8所示,OE为输出使能端(低电平有效),也就是要使该芯片工作,此脚必须为低电平;1D-8D为数据输入端;1Q-8Q为数据输出端;LE为输出控制端。
图8 74HC573引脚图 图9 74HC573真值表
图9为74HC573的真值表,真值表可以直观的表示数字芯片的工作特性,也就是要正确的使用数字芯片,必须学会看真值表。在图9中,L表示低电平,H表示高电平,X表示任意电平,Z表示高阻态,即,可以为高电平,也可以为低电平,高或低由与它相连的其它电气状态决定;Q0表示上一次电平状态。
由图9真值表可以看出,当OE为高电平时,无论控制端LE和数据端为什么电平,输出Q都为高阻态,也就是电平未知,此时锁存器处于不可控的状态,而我们使用该芯片肯定是要控制它以完成相应的功能,所以实验板上两块芯片在硬件上均直接接地,相当于直接给低电平。
当OE为低电平时,LE为高时,D和Q同时为H或L;LE为低时,无论D为何种状态,Q都保持上一次的数据状态。也就是说LE为高电平时,Q端的数据随D端数据变化而变化,LE为低电平时,Q端的数据保持为LE端由高电平变为低电平之前Q端的数据状态。
在使用时,我们一般把LE端接单片机的一个引脚,而把数据输入端D接单片机的8个引脚,此时我们就可以通过单片机控制LE端电平的高低和数据端的电平状态来决定锁存器数据输出端的输出状态。
讲到这里,相信大家已经对74HC573基本了解了,锁存器的作用很多,在实验板上主要起到两个作用,一个就是解决驱动问题,这一点前面已经说过,单片机I/O口输出的电流太小,不足以驱动数码管,此时就可以利用锁锁器来实现;再一个就是节约单片机的I/O口,这一点后面会解释到。
2数码管静态显示
明白了显示原理后,我们就可以对数码管进行操作了,让我们先看看一下实验板的原理图。
实验板上的数码管为两个3位一体的数码管,共同组成一个6位8段共阳极数码管,
相同段的发光二极管阴极全部接在一起,引出8个引脚abcdefgdp,分别接到锁存器的数据输出口,而锁存器74hc573的数据输入口直接接到单片机P1口的8信引脚,注意此时P0口同时接了10K的上拉电阻;每一位数码管内部发光二极管阳极接在一起,然后分别引出6个脚w1w2w3w4w5w6,并能过锁存器74hc573接到了单片机P1口的6个脚。两个锁存器的锁存端分别与单片机的P2^6和P2^7相连。
也就是这六位数码管“段选”全部连在一起,而“位选”是可以独立控制的,我们可通过控制位选信号而选择让哪几个数码管发光,具体显示的内容可以通过段选信号进行,但由于所有段选是全部连在一起的,送入所在数码管的段选信号必定相同,所以位选选通的数码管上显示的数字始终一样,数码管的这种显示方式称为静态显示。
下面我们就写一个简单的程序让第一个数码管显示一个8字。先来分析如下:让第一个数码管显示8字,那么别的数码管的位选就要关闭,即只打开第一个数码管的位选。在操作时,我从头先给U2数码管的锁存端一个高电平,然后将数据从单片机的口P0直接送出到锁存器的U2的数据输出端,然后再关闭U2锁存器。由于实验板上的数码管为共阳极,所以位选选通时为高电平,位选关闭时为低电平。即只有W1端对应的数据为1,其它的都为0,因此P0口呆输出的数据0x01;(二进制为0000 0001)。位选确定后,再确定段选,要显示8,那么只有h段为0,其余段为1,所以用操作U2的方法一样操作U1,让U1数据输出端输出0x7f(二进制为0111 1111)
程序:单片机显示8
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;
sbit wei=P2^7;
void main()//第一个数码管显示8
{
while(1)
{
duan=1;
P0=0x7f;
duan=0;
wei=1;
P0=0xfe;
wei=0;
while(1);
}
}
下面先下载到实验板上看现象。
通过上面的现象我们实现了数码管静态显示的功能,这里大家家可能已经知道,程序中段用了单片机的8个引脚,而位用到了单片机的6个引脚,按理说我们一共需要14个引脚,而因为锁存器的原因,实际上我们只用到了P1口8个脚就实现了,这就是上面讲的锁存器的第二个作用,使用锁存器可以达到节约单片机的I/O口的作用。
(3) [数码管显示]数码管显示原理及编码(段码)
数码管原理(显示)及编码(段码)
常用的7段数码管由发光二极管(组合)构成,如下图:
分为:共阳极和共阴极(如上图)
如果显示“0”,共阳极为:abcdefg
dp ,dp为对应最高位,a为对应最低位,编码:11000000
,16进制0xC0,共阴极正好相反:00111111,16进制0x3f。
以此类推。
共阳极数码管的0 到f的段编码:0xc0,0xf9,0xa4,0xb0,//0~30x99,0x92,0x82,0xf8,//4~70x80,0x90,0x88,0x83,//8~b0xc6,0xa1,0x86,0x8e //c~f
共阴极数码管0到f的短编码:0x3f,0x06,0x5b,0x4f, //0~30x66,0x6d,0x7d,0x07, //4~70x7f,0x6f,0x77,0x7c, //8~b0x39,0x5e,0x79,0x71 //c~f