说了那么多的LED,再说估计就真挨骂了,这节缘缘带你们去看看两个在数码管显示时最常用到的两个芯片吧,看看它们是怎么工作,想信你一定会有兴趣的:
以前我们控制数码管时,都用两个P口去控制它们,那么如果单片机的其它P口都被占用了,只有一个P口时,能不能控制8个数码管呢,答案是肯定的,借助外围芯片可以很容易实现,这里我们用两种简单的芯片控制,其实这两个芯片就是74 573类与74 138类的,缘缘用的是74HC573和74HC138,其它的命名不一样,但工作原理是一样的,我们一起看看吧:
74HC573:
记得缘缘最开始时,常被这个芯片搞昏了头,什么段选控制了,位选控制了,咱先不用管它,先看看这个74HC573芯片的工作原理是怎么回事,虽然有芯片的说明文档,但缘缘觉得那看起来不易理解,所以缘缘就根据说明文件,画了一个图来:
我们看到,这个573芯片是20管脚的,除电源的两根外,有8根输入和输出,这样就只剩下了两个管脚了:即OE和LE,那么这两个是干什么的呢,OE是三态使能输入,低电平有效,意思就是当这个管脚接成低电平时,这个芯片才会工作,不然输入和输入都不工作,LE是什么意思呢,锁存使能输入,意思就是控制输入与输出状态的,我们看到,当LE为低电平0时,输入有效,但输出无效,当LE为高电平1时,输入有效,输出也有效。
通过前面的分析,我们得知,我们控制这个芯片时只控制OE和LE就行了,一般地,要设置成芯片输入输出有效工作,所以直接把OE设成低电平,即接地状态,而对LE控制来控制是否输出,以达到应用要求,8根输入接单片机P口,8根输出接外载,那么我们看看它是如何控制8个数码管的:
我们看到,控制8个数码管时(记得这8个数码管后面还有8个PNP三极管哦),用了两个74HC573的芯片,一个接在数码管的段上,一个接在数码管的位上,但它们的输入却接在一个端口上,还有两个LE控制控制线也接了出来,这时,如果我们给这个输入端口送一个数值,如果两个LE都是0的情况下,它不会输出,如果其中一个是1了,那么它会输出,明白了这个道理了,我们就送一次位的值,再送一次段的值,当送位时,与位连接的573的LE是高电平1,芯片处在输出状态,段的LE是低电平0,处于紧锁状态不输出,反之也一样,这样,我们就可以控制显示8个数码管了,并以不同的内容和位,这样就达到了我们的要求,并用1个P口送数据,节省了单片机宝贵的IO口,那么我们写个程序看看效果吧:
#include< reg52.h >
#define uint unsigned int
#define uchar unsigned char
uchar temp,aa,numdu,numwe;
sbit dula=P2^7;//段573芯片的LE控制端口
sbit wela=P2^6;//位573芯片的LE控制端口
uchar code duan={
~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};//段的代码(共阴极与共阳极不一样哦)
uchar code wei={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位的代码
void delay(uint z);
void main()
{
numdu=0;
numwe=0;
aa=0;
while(1)
{
delay(1000);
delay(1000);
if(numdu==16)
numdu=0;
dula=1;
P0=duan;
dula=0;
wela=1;
P0=wei;
wela=0;
numwe++;
if(numwe==8)
numwe=0;
delay(1000);
delay(1000);
numdu++;
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
怎么样,简单吧,下载程序试试吧,当以后看到程序时,如果有类似的写法时,还会不明白吗?
573说完了,我们再看看138是怎么回事:
74HC138:
同样,说明文件不易理解,缘缘还是给你看张图吧:
我们看到这个芯片是16管脚的,除了两根电源与8根输出端口外,就只剩下了6个端口了,除了三个数据输入端口(ABC)外,有3个使能输入端(G1、G2A、G2B),这三个使能端的电平是二低一高有效,也就是只有在这种情况下,输入与输出才能正常工作,所以在电路应用中,将两个低电平的接地,只控制一个高电平的,当高电平时,输入输出有效,当为低电平时,输入输出无效,对于ABC的组合,上图中标示得很清楚了,也就是ABC的高低电平排列组合会让8个输出端的管脚进行低电平0输出,我们先看看在电路中是如何应用的(一般在数码管显示时与573等芯片配合使用)
我们写个程序看看是怎么样的效果:
#include
#define uint unsigned int
#define uchar unsigned char
uchar numdu,numwei;
sbit dula=P2^7;//控制573段码显示
sbit wei=P2^6;//控制138输出
sbit a=P2^0;//138数据端口abc
sbit b=P2^1;
sbit c=P2^2;
uchar code table={
~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
void delay(uint z);
void main()
{
numdu=0;
numwei=0;
wei=1;//1为138输出有效
while(1)
{
dula=1;
P0=table;
dula=0;
if(numdu==16)
numdu=0;
switch(numwei) //使用switch 语句控制位选 也可以是用查表的方式
{
case 0:a=0; b=0; c=0; break;
case 1:a=1; b=0; c=0; break;
case 2:a=0; b=1; c=0; break;
case 3:a=1; b=1; c=0; break;
case 4:a=0; b=0; c=1; break;
case 5:a=1; b=0; c=1; break;
case 6:a=0; b=1; c=1; break;
case 7:a=1; b=1; c=1; break;
}
numwei++;
if(numwei==8)
numwei=0;
delay(2000);
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
这里有个switch语句,那么这条语句是啥意思呢?
C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:
switch(表达式){
case常量表达式1: 语句1;
case常量表达式2: 语句2;
…
case常量表达式n: 语句n;
default:语句n+1;
}
其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
【例4.9】
main(){
int a;
printf("input integer number: ");
scanf("%d",&a);
switch (a){
case 1:printf("Mondayn");
case 2:printf("Tuesdayn");
case 3:printf("Wednesdayn");
case 4:printf("Thursdayn");
case 5:printf("Fridayn");
case 6:printf("Saturdayn");
case 7:printf("Sundayn");
default:printf("errorn");
}
}
本程序是要求输入一个数字,输出一个英文单词。但是当输入3之后,却执行了case3以及以后的所有语句,输出了Wednesday 及以后的所有单词。这当然是不希望的。为什么会出现这种情况呢?这恰恰反应了switch语句的一个特点。在switch语句中,“case 常量表达式”只相当于一个语句标号, 表达式的值和某标号相等则转向该标号执行,但不能在执行完该标号的语句后自动跳出整个switch 语句,所以出现了继续执行所有后面case语句的情况。 这是与前面介绍的if语句完全不同的,应特别注意。
为了避免上述情况,C语言还提供了一种break语句,专用于跳出switch语句,break 语句只有关键字break,没有参数。在后面还将详细介绍。修改例题的程序,在每一case语句之后增加break 语句, 使每一次执行之后均可跳出switch语句,从而避免输出不应有的结果。
【例4.10】
main(){
int a;
printf("input integer number: ");
scanf("%d",&a);
switch (a){
case 1:printf("Mondayn");break;
case 2:printf("Tuesdayn"); break;
case 3:printf("Wednesdayn");break;
case 4:printf("Thursdayn");break;
case 5:printf("Fridayn");break;
case 6:printf("Saturdayn");break;
case 7:printf("Sundayn");break;
default:printf("errorn");
}
}
在使用switch语句时还应注意以下几点:
看明白了吗,这条语句就是先以switch括号中的值为参照,然后依次判断大括号里面的值,如果与switch后面括号中的值一样时,就执行后面的语句,否则就会跳出这条语句来。
现在的亲对这两个芯片很熟悉了,上面的原理图是缘用芯片的实际管脚绘制的,所以亲们在应用这两个芯片的时候,就按缘缘画的管脚去接线,肯定不会错的,祝亲们成功哦,缘缘就不做这个实验板了,亲们,咱们下节见哦。