C51单片机day05-键盘

键盘

例题1:如果P3.4口按下去的时候,我们把第一个发光二极管点亮,松手的时候第一个发光二极管熄灭:

#include <reg52.h>
sbit d1=P1^0;
sbit key1=P3^4;

void main()
{
	P3=0xff;
	while(1)
	{
		if(key1==0)
			d1=0;
		else
			d1=1;
	}
}

续例题1:现在让键盘每按一次,设一个数加1并让该数显示在第一个数码管上:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar num;
void main()
{
	wela=1;
	P0=0xfe;
	wela=0;
	P3=0xff;
	while(1)
	{
		if(key1==0)
		{
			d1=0;
			num++;
			if(num==10)
				num=0;
			while(!key1);
		}
		else
			d1=1;
		dula=1;
		P0=table[num];
		dula=0;
	}
}

注意:其中数字会出现跳跃、乱象或抖动的现象,原因是:键盘在闭合和断开是,触电会存在抖动现象;
在这里插入图片描述

  • 但如何消除抖动呢?(图右侧电路是硬件消抖)
    答:用延时函数进行消抖,此单片机抖动大概是5ms,按键被按下后会由20ms的低电平延迟,所以不用担心会收不到信号
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar num;
void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void main()
{
	wela=1;
	P0=0xfe;
	wela=0;
	P3=0xff;
	while(1)
	{
		if(key1==0)
		{
			delay(10);
			if(key1==0)
			{
			d1=0;
			num++;
			if(num==10)
				num=0;
			}
		while(!key1);
		delay(10);
		while(!key1);
		}
		else
			d1=1;
		dula=1;
		P0=table[num];
		dula=0;
	}
}

矩阵键盘

在这里插入图片描述

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};
uchar num,temp;
void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void main()
{
	dula=1;
	P0=0;
	dula=0;
	wela=1;
	P0=0xc0;
	wela=0;
	while(1)
	{
		P3=0xfe;//第一行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xee:num=1;
						break;
					case 0xde:num=2;
						break;
					case 0xbe:num=3;
						break;
					case 0x7e:num=4;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
				dula=1;
				P0=table[num-1];
				dula=0;
			}
		}

		P3=0xfd;//第二行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xed:num=5;
						break;
					case 0xdd:num=6;
						break;
					case 0xbd:num=7;
						break;
					case 0x7d:num=8;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
				dula=1;
				P0=table[num-1];
				dula=0;
			}
		}

		P3=0xfb;//第三行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xeb:num=9;
						break;
					case 0xdb:num=10;
						break;
					case 0xbb:num=11;
						break;
					case 0x7b:num=12;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
				dula=1;
				P0=table[num-1];
				dula=0;
			}
		}

		P3=0xf7; //第四行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xe7:num=13;
						break;
					case 0xd7:num=14;
						break;
					case 0xb7:num=15;
						break;
					case 0x77:num=16;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
				dula=1;
				P0=table[num-1];
				dula=0;
			}
		}

	}
}

矩阵键盘写成子函数如下:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0};
uchar num,temp,num1;
uchar keyscan();
void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
} 
void main()
{
	num=17;
	dula=1;
	P0=0;
	dula=0;
	wela=1;
	P0=0xc0;
	wela=0;
	while(1)
	{
		num1=keyscan();
		dula=1;
		P0=table[num1-1];
		dula=0;

	}
}

uchar keyscan()
{
		P3=0xfe;//第一行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xee:num=1;
						break;
					case 0xde:num=2;
						break;
					case 0xbe:num=3;
						break;
					case 0x7e:num=4;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
			}
		}

		P3=0xfd;//第二行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xed:num=5;
						break;
					case 0xdd:num=6;
						break;
					case 0xbd:num=7;
						break;
					case 0x7d:num=8;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
			}
		}

		P3=0xfb;//第三行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xeb:num=9;
						break;
					case 0xdb:num=10;
						break;
					case 0xbb:num=11;
						break;
					case 0x7b:num=12;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
			}
		}

		P3=0xf7; //第四行
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			while(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xe7:num=13;
						break;
					case 0xd7:num=14;
						break;
					case 0xb7:num=15;
						break;
					case 0x77:num=16;
						break;

				}
				while(temp!=0xf0)//松手检测
				{
					temp=P3;
					temp=temp&0xf0;
				}
			}
		}
return num;
}

练习

-练习题1:1.数码管前三位显示一个跑表,从000到999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。(用定时器设计表)。

#include<reg52.h> 
#include <intrins.h> 
#define uint unsigned int 
#define uchar unsigned char 
sbit dula=P2^6;
sbit wela=P2^7;
sbit s2=P3^4;
uchar code table[]={ 
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0x76,0x79,0x38,0x3f,0};
uchar flag,t0,ge,shi,bai;
uint shu;
void init();             
void display(uchar aa,uchar bb,uchar cc);
void delay(uint z) 
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void main()    
{
	init();
	while(1)
	{
		display(bai,shi,ge);
		if(s2==0)
		{
			delay(10);
			if(s2==0)
			{
				TR0=0;
				while(!s2)
					display(bai,shi,ge);
				TR0=1;
			}
		}		
	}
}

void init()        
{
	TMOD=0x01;
	TH0=(65536-10000)/256; 
	TL0=(65536-10000)%256;
	EA=1;
	ET0=1;
	TR0=1;
}

void timer0() interrupt 1 
{
	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	shu++;
	if(shu==1000)
		shu=0;
	bai=shu/100;
	shi=shu%100/10;
	ge=shu%10;
		
}


void display(uchar aa,uchar bb,uchar cc)
{
        dula=1;
		P0=table[aa];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfe;
		wela=0;
		delay(1);

       	dula=1;
		P0=table[bb];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfd;
		wela=0;
		delay(1);

       dula=1;
		P0=table[cc];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfb;
		wela=0;
		delay(1);
}
  • 练习题2:在上题的基础上,用另外三个独立键盘实现按下第一个时计时停止,按下第二个时计时开始,按下第三个是计数值清零从头开始。
#include<reg52.h> 
#include <intrins.h> 
#define uint unsigned int 
#define uchar unsigned char 
sbit dula=P2^6;
sbit wela=P2^7;
sbit s2=P3^4;
sbit s3=P3^5;
sbit s4=P3^6;
sbit s5=P3^7;
uchar code table[]={ 
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0x76,0x79,0x38,0x3f,0};
uchar flag,t0,ge,shi,bai;
uint shu;
void init();             
void display(uchar aa,uchar bb,uchar cc);
void delay(uint z) 
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
void main()    
{
	init();
	while(1)
	{
		display(bai,shi,ge);
		if(s2==0)
		{
			delay(10);
			if(s2==0)
			{
				TR0=0;
				while(!s2)
					display(bai,shi,ge);
				TR0=1;
			}
		}
		if(s3==0)
		{
			delay(10);
			if(s3==0)
			{
				while(!s2)
					display(bai,shi,ge);
				TR0=0;
			}
		}
		if(s4==0)
		{
			delay(10);
			if(s4==0)
			{
				while(!s2)
					display(bai,shi,ge);
				TR0=1;
			}
		}
		if(s5==0)
		{
			delay(10);
			if(s5==0)
			{
				while(!s2)
					display(bai,shi,ge);
				shu=0;
			}
		}		
	}
}

void init()        
{
	TMOD=0x01;
	TH0=(65536-10000)/256; 
	TL0=(65536-10000)%256;
	EA=1;
	ET0=1;
	TR0=1;
}

void timer0() interrupt 1 
{
	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	shu++;
	if(shu==1000)
		shu=0;
	bai=shu/100;
	shi=shu%100/10;
	ge=shu%10;
		
}


void display(uchar aa,uchar bb,uchar cc)
{
        dula=1;
		P0=table[aa];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfe;
		wela=0;
		delay(1);

       	dula=1;
		P0=table[bb];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfd;
		wela=0;
		delay(1);

       dula=1;
		P0=table[cc];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfb;
		wela=0;
		delay(1);
}
  • 练习题3:按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4…
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar temp;
uint num,num1;
void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}
uint keyscan();
void display(uchar,uchar,uchar);
void main()
{
	dula=1;
	P0=0;
	dula=0;
	wela=1;
	P0=0xc0;
	wela=0;
	while(1)
	{
		num1=keyscan();
		display(num1/100,num1%100/10,num1%10);
	}
}
void display(uchar aa,uchar bb,uchar cc)
{
        dula=1;
		P0=table[aa];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfe;
		wela=0;
		delay(1);

       	dula=1;
		P0=table[bb];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfd;
		wela=0;
		delay(1);

       dula=1;
		P0=table[cc];
		dula=0;
		P0=0xff;
		wela=1;
		P0=0xfb;
		wela=0;
		delay(1);
}
uint keyscan()
{
	P3=0xfe;
	temp=P3;
	temp=temp&0xf0;
	while(temp!=0xf0)
	{
		delay(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
		switch(temp)
		{
			case 0xee:num=1;
				break;
			case 0xde:num=4;
				break;
			case 0xbe:num=9;
				break;
			case 0x7e:num=16;
				break;
		}
		while(temp!=0xf0)
		{
			temp=P3;
			temp=temp&0xf0;
		}
		}
	}

	P3=0xfd;
	temp=P3;
	temp=temp&0xf0;
	while(temp!=0xf0)
	{
		delay(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
		switch(temp)
		{
			case 0xed:num=25;
				break;
			case 0xdd:num=36;
				break;
			case 0xbd:num=49;
				break;
			case 0x7d:num=64;
				break;
		}
		while(temp!=0xf0)
		{
			temp=P3;
			temp=temp&0xf0;
		}
		}
	}


	P3=0xfb;
	temp=P3;
	temp=temp&0xf0;
	while(temp!=0xf0)
	{
		delay(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
		switch(temp)
		{
			case 0xeb:num=81;
				break;
			case 0xdb:num=100;
				break;
			case 0xbb:num=121;
				break;
			case 0x7b:num=144;
				break;
		}
		while(temp!=0xf0)
		{
			temp=P3;
			temp=temp&0xf0;
		}
		}
	}


	P3=0xf7;
	temp=P3;
	temp=temp&0xf0;
	while(temp!=0xf0)
	{
		delay(5);
		temp=P3;
		temp=temp&0xf0;
		while(temp!=0xf0)
		{
			temp=P3;
		switch(temp)
		{
			case 0xe7:num=169;
				break;
			case 0xd7:num=196;
				break;
			case 0xb7:num=225;
				break;
			case 0x77:num=256;
				break;
		}
		while(temp!=0xf0)
		{
			temp=P3;
			temp=temp&0xf0;
		}
		}
	}
return num;
}

松手检测:当数字键盘按下时数码管不会显示数字,但当松手时数码管才会有示数变化:

while(temp!=0xf0)
{
	temp=P3;
	temp=temp&0xf0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值