①透明模式测试(~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; } } }