单片机输入电路中最常用的是键盘,键盘分为两类:一类是独立键盘;另一类是矩阵键盘。下面分别是51单片机外围电路中常见的独立按键电路以及4*4矩阵键盘电路:

独立键盘

矩阵键盘

 

对于键盘操作还有一个重要的问题,按键抖动现象。即按一下按键然后松开手,由于单片机运行速度很快,能够多次运行到键盘程序,往往会认为按了多次按键。消除键盘抖动的方法有硬件消抖和软件消抖。最常用的是软件消抖,即在程序中检测到按键按下后,延迟一段时间,在按键程序结束后,在延时一段时间。

下面结合之前介绍过的输入电路与按键实现两个应用实例。

1、按下按键在1602上显示对应的数字,再按下一个按键后面显示℃,再按下一个按键后清零,为下一次输入做准备。

#include <reg52.h>
#include "LCD1602.h"
#include <intrins.h>
uchar code table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
uchar tab1;
int keyscan(void)
{
	uchar i,temp,key=16;
	for(i=0;i<4;i++)
	{
		P3=_crol_(0xfe,i);
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
			delay(5);
			temp=P3;
			temp=temp&0xf0;
			if(temp!=0xf0)
			{
				temp=P3;
				switch(temp)
				{
					case 0xee:key=0;break;
					case 0xde:key=1;break;
					case 0xbe:key=2;break;
					case 0x7e:key=3;break;
					case 0xed:key=4;break;
					case 0xdd:key=5;break;
					case 0xbd:key=6;break;
					case 0x7d:key=7;break;
					case 0xeb:key=8;break;
					case 0xdb:key=9;break;
					case 0xbb:key=10;break;
					case 0x7b:key=11;break;
					case 0xe7:key=12;break;
					case 0xd7:key=13;break;
					case 0xb7:key=14;break;
					case 0x77:key=15;break;
					default:break;
				}
				while((temp&0xf0)!=0xf0)
				{
					temp=P3;
					temp=temp&0xf0;
				}
			}
		}
	}
	return key;
}
void mian()
{
	uchar i,a,key1;
	Lcd_Init();
	while(1)
	{
		write_data(0x80+table[0]);
		key1=keyscan();
		if(key1==10)
		{
			 write_com(0x01);
			 write_com(0x80);
			 a=0;
		}
		if(key1<10)
		{
			write_com(0x80+table[a]);
			delay(5);
			tab1=key1;
			write_data(tab1='0');
			a++;
		}
		if(key1==11)
		{
			write_com(0x80+table[a]);
			write_data(0xdf);
			delay(20);
			write_com(0x80+table[a+1]);
			delay(5);
			write_data('C');
		} 
	}
}

2、按下按键在8位数码管上显示相应的数字。

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit duan=P2^6;
sbit wei=P2^7;
uchar code 	table[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f,
0x76,0x79,0x38,0x3f,0x5b,0x6};
uchar temp,num,num1;
void delay()
{
  uchar x,y;
  for(y=0;y<100;y++)
     for(x=0;x<10;x++);
} 
main()
{
	duan=1;
	P0=0;
	duan=0;
	wei=1;
	P0=0xc0;
	wei=0;
  	P1=0xfe;
	while(1)
	{
		P3=0xfe;
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    delay();
			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;
				}	  //松手检测
				P1=_crol_(P1,num);
			}
		} 
		P3=0xfd;
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    delay();
			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;
				}	 
				duan=1;
				P0=table[num-1];
				duan=0;
			}
		}
		P3=0xfb;
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    delay();
			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;
				}	
				duan=1;
				P0=table[num-1];
				duan=0;
			}
		}
	    P3=0xf7;
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    delay();
			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;
				}	
				duan=1;
				P0=table[num-1];
				duan=0;
			}
		}
	}
}