①透明模式测试(~OE=0,LE=1)
这种模式下,相当于一个数据缓冲器,Q延迟D输出相同的电平,通过单个数码显示0~F能够得到验证。
②锁存读寄存器(~OE=0,LE=0)
将LE拉低,输入端的变化对输出端没有影响,这时在第一种模式的基础上,寄存器中的数据被锁存。
③锁存输出无效(~OE=1,LE=0)
此模式下,不工作,没有输出,不工作。
/*
验证程序出错,特别注意使用P0口驱动某一模块的时候要加上拉电阻,尽量不要使用P0口。如果把P0全部替换为P2程序也是不正确的,因为定义的按键也是P2,这时会一直执行while(!key1);在程序执行完第一次0~9的显示后,P2^0和P2^2都被清零,且一直保持,这样就会停留显示9,因此根据电路的焊接情况将P2全部替换为P3,执行程序能够达到预想的功能。
*/
#include<reg52.h>
unsigned int tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit OE=P1^0;
sbit LE=P1^1;
sbit key1=P2^0;
sbit key2=P2^2;
void delayms(unsigned int cnt)
{
unsigned int x,y;
for(x=cnt;x>0;x--)
for(y=110;y>0;y--);
}
main()
{
unsigned int n;
OE=0;
LE=1;
while(1)
{
for(n=0;n<10;n++)
{
P0=tab[n];
delayms(1000);
}
if(!key1) //锁存读寄存器模式
{
delayms(10);
while(!key1); //防止长按不放;
if(key1)
{
delayms(10);
if(key1)
{
OE=0;
LE=0;
}
}
}
if(!key2) //锁存输出无效
{
delayms(10);
while(!key2);
if(key2)
{
delayms(10);
if(key2)
{
OE=1;
LE=1;
}
}
}
}
}
/*
OE直接接地,不需要任何操作,OE置高电平没有意义。修改程序后确实能够实现循环显示0~f,但是按键失灵,也就是无法操纵LE清零。按键按下后P1^1没有清零。也许是老毛病,在有较长时间延时函数出现的地方,不能在主函数中出现按键检测,这样是检测不到信号的,以前出现过这种情况,因为按键信号和延时函数时间之比相差上百倍,只有在那几百分之一秒的适当时间按下按键才能被检测,这种几率是很小的,所以按键会失效。
*/
#include<reg52.h>
unsigned int tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit LE=P1^1;
sbit key1=P2^0;
sbit key2=P2^2;
void delayms(unsigned int cnt)
{
unsigned int x,y;
for(x=cnt;x>0;x--)
for(y=110;y>0;y--);
}
main()
{
unsigned int n,OE;
OE=0;
LE=1;
while(1)
{
for(n=0;n<10;n++)
{
P3=tab[n];
delayms(1000);
}
if(!key1)
{
delayms(10);
while(!key1);
if(key1)
{
delayms(10);
if(key1)
LE=0;
}
}
if(!key2)
{
delayms(10);
while(!key2);
if(key2)
{
delayms(10);
if(key2)
LE=1;
}
}
}
}
/*
修改按键程序,采用中断或者定时扫描。因为接线原因,P3口已被使用,所以采用定时扫描进行按键检测。但是我的AVR Fighter和Progisp突然间都不能使用了,出现avr fighter没有发现USB设备,查找硬件和驱动程序都没有问题,可能是电脑出现了什么问题,在系统还原之前换了一台电脑,avr fighter还是不能用,但是Progisp能够烧录。此程序在按下key1的时候能够进行锁定,但是key2失效,按下Key2的时候也能出现锁定,总是出现混乱。
万用表检测P1^0口的电平,在key1被按下的时候确实被清零,在key2按键被按下的时候置一。但是P1^0口接LE,在按键key2被按下的时候应该能够重新跳进主程序,继续循环显示,但是没有变化。
*/
#include<reg51.h>
unsigned int tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit LE=P1^0;
sbit key1=P2^0;
sbit key2=P2^2;
void delayms(unsigned int cnt)
{
unsigned int x,y;
for(x=cnt;x>0;x--)
for(y=110;y>0;y--);
}
main()
{
unsigned int n;
LE=1;
TMOD|=0x01;
EA=1;
TR0=1;
ET0=1;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
while(1)
{
for(n=0;n<10;n++)
{
P3=tab[n];
delayms(1000);
}
}
}
void timer0(void) interrupt 1 using 0
{
TH0=(65536-1000)/256;//1MS检测一次
TL0=(65536-1000)%256;
if(!key1)
{
delayms(10);
while(!key1);
if(key1)
{
delayms(10);
if(key1)
LE=0;
}
}
if(!key2)
{
delayms(10);
while(!key2);
if(key2)
{
delayms(10);
if(key2)
LE=1;
}
}
}
/*
使用调试模式,寄存器组发生冲突,去掉using x后,能够跳至主程序。一般情况下在定期器和中断中不要使用using,自动进行分配和优化比较好!所谓下降沿触发,指的是进入锁存模式的时候!
*/
/*
373的使用同573基本功能一样,跳变沿触发锁存!注意实际中的引脚是交*排列的。下面使用proteus进行模拟演示!上次上课使用using的时候要特别留意,一般不使用,自动重载的含义(10模式2),第三种模式(11模式3)一般用于同步计数。
*/
#include<reg51.h>
unsigned int tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit LE=P2^0;
sbit key1=P2^1;
sbit key2=P2^2;
void delayms(unsigned int cnt)
{
unsigned int x,y;
for(x=cnt;x>0;x--)
for(y=110;y>0;y--);
}
main()
{
unsigned int n;
LE=1;
TMOD|=0x01;
EA=1;
TR0=1;
ET0=1;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
while(1)
{
for(n=0;n<10;n++)
{
P1=tab[n];
P3=0x0;
delayms(1000);
P3=0xff;
delayms(1000);
}
}
}
void timer0(void) interrupt 1 using 2
{
TH0=(65536-20000)/256;//20MS检测一次
TL0=(65536-20000)%256;
if(!key1)
{
delayms(5);
while(!key1);
if(key1)
{
delayms(5);
if(key1)
LE=0;
}
}
if(!key2)
{
delayms(5);
while(!key2);
if(key2)
{
delayms(5);
if(key2)
LE=1;
}
}
}
