电路原理图:

独立按键(S4、S5、S6、S7)

        当跳线帽接通J5的2 3引脚时,P3.6接地,检测P3.0、P3.1、P3.2、P3.3,若检测到该引脚为低电平,则该按键被按下(J5跳线帽接BTN)。

代码实现:当S7、S6、S5、S4被按下时,数码管依次显示1、2、3、4

#include"reg51.h"
#include"intrins.h"
unsigned char code SMG_DuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
																 0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
																 0xbf,0xff};
																 
sbit S7=P3^0;
sbit S6=P3^1;
sbit S5=P3^2;																 
sbit S4=P3^3;
																 
void Delay10ms()		//10ms延时(消抖)
{
	unsigned char i, j;
 
	i = 108;
	j = 145;
	do
	{
		while (--j);
	} while (--i);
}
 
	
void Init_74HC138(unsigned char n)
{
	switch(n)
	{
		case 4:
			P2=(P2 & 0x1f) | 0x80;
			break;
		case 5:
			P2=(P2 & 0x1f) | 0xa0;
			break;
		case 6:
			P2=(P2 & 0x1f) | 0xc0;
			break;
		case 7:
			P2=(P2 & 0x1f) | 0xe0;
			break;
	}
}
//********数码管显示子函数,smg_val为第一位数码管显示的数字********
void SMG_Disp(unsigned char smg_val)
{
	Init_74HC138(6);
	P0=0x01;//选通数码管第一位
	Init_74HC138(7);
	P0=SMG_DuanMa[smg_val];	
}
 
//********按键扫描函数********
void ScanKeys()
{
	if(S7 == 0)    //检测到S7按下
	{
			Delay10ms(); //延时消抖
			if(S7 == 0)//确定S7按下
			{					
					SMG_Disp(1);//当S7被按下时,数码管显示“1”
			}
	}
	if(S6 == 0)
	{
			Delay10ms();
			if(S6 == 0)
			{					
					SMG_Disp(2);//当S6被按下时,数码管显示“2”
			}
	}
	
	if(S5 == 0)
	{
			Delay10ms();
			if(S5 == 0)
			{
				SMG_Disp(3);//当S5被按下时,数码管显示“3”
			}	
	}
	
	if(S4 == 0)
	{
			Delay10ms();
			if(S4 == 0)
			{				
				SMG_Disp(4);//当S4被按下时,数码管显示“4”
			}
	}
	
}
 
void main()
{
	while(1)
	{
		ScanKeys();
	}
}

矩阵键盘

思路:先扫描行,再扫描列(也可先扫描列,再扫描行)。令其中某一行或某一列为0(等同于独立键盘的接地),判断对应的位置的列或行是否为0,从而确定是哪一个按键被按下(此时J5跳线帽接KBD)。

代码实现:当第1行第2列有按键按下时,数码管第二位第三位分别显示1 2; 当第3行第2列有按键按下时,数码管第二位第三位分别显示3 2......当按键松开,数码管熄灭。

#include"reg51.h"
#include"intrins.h"
sfr P4=0xc0;//定义P4,便于程序的识别和运行
 
sbit R1=P3^0;//第1行
sbit R2=P3^1;//第2行
sbit R3=P3^2;//第3行
sbit R4=P3^3;//第4行
 
sbit C1=P4^4;//第1列
sbit C2=P4^2;//第2列
sbit C3=P3^5;//第3列
sbit C4=P3^4;//第4列
 
//数码管段码表
unsigned char code SMG_DuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
																 0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
																 0xbf,0xff};
 
void Init74HC138(unsigned char n)
{
	switch(n)
	{
		case 4:
			P2=(P2 & 0x1f) | 0x80;
			break;
		case 5:
			P2=(P2 & 0x1f) | 0xa0;
		break;
		case 6:
			P2=(P2 & 0x1f) | 0xc0;
		break;
		case 7:
			P2=(P2 & 0x1f) | 0xe0;
		break;
	}
}
 
void SMG_Disp(unsigned char pos,unsigned char val)
{
	Init74HC138(6);
	P0=(0x01<<pos);
	Init74HC138(7);
	P0=SMG_DuanMa[val];
}
 
 
void Delay10ms()		
{
	unsigned char i, j;
 
	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}
//************数码管全灭子函数**************************
void SMG_Mie()
{
			SMG_Disp(0,17);
			Delay10ms();
			SMG_Disp(1,17);
			Delay10ms();
			SMG_Disp(2,17);
			Delay10ms();
			SMG_Disp(3,17);
			Delay10ms();
			SMG_Disp(4,17);
			Delay10ms();
			SMG_Disp(5,17);
			Delay10ms();
			SMG_Disp(6,17);
			Delay10ms();
			SMG_Disp(7,17);
			Delay10ms();
}
//************按键扫描函数**************************
void ScanKeys()
{
	
	R1=0;             //扫描第一行
	R2=R3=R4=1;
	C1=C2=C3=C4=1;
	if(C1 == 0)
	{
		while(C1 == 0)//判断按键是否释放,没有释放则显示按键序号
		{
			SMG_Disp(1,1);
			Delay10ms();
			SMG_Disp(2,1);
			Delay10ms();
		}
		SMG_Mie();//按键松开,数码管熄灭
	}
	else if(C2 == 0)
	{
		while(C2 == 0)
		{
			SMG_Disp(1,1);
			Delay10ms();
			SMG_Disp(2,2);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C3 == 0)
	{
		while(C3 == 0)
		{
			SMG_Disp(1,1);
			Delay10ms();
			SMG_Disp(2,3);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C4 == 0)
	{
		while(C4 == 0)
		{
			SMG_Disp(1,1);
			Delay10ms();
			SMG_Disp(2,4);
			Delay10ms();
		}
				SMG_Mie();
	}
	
	R2=0;             //扫描第二行
	R1=R3=R4=1;
	C1=C2=C3=C4=1;
	if(C1 == 0)
	{
		while(C1 == 0)
		{
			SMG_Disp(1,2);
			Delay10ms();
			SMG_Disp(2,1);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C2 == 0)
	{
		while(C2 == 0)
		{
			SMG_Disp(1,2);
			Delay10ms();
			SMG_Disp(2,2);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C3 == 0)
	{
		while(C3 == 0)
		{
			SMG_Disp(1,2);
			Delay10ms();
			SMG_Disp(2,3);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C4 == 0)
	{
		while(C4 == 0)
		{
			SMG_Disp(1,2);
			Delay10ms();
			SMG_Disp(2,4);
			Delay10ms();
		}
				SMG_Mie();
	}
	
	R3=0;             //扫描第三行
	R1=R2=R4=1;
	C1=C2=C3=C4=1;
	if(C1 == 0)
	{
		while(C1 == 0)
		{
			SMG_Disp(1,3);
			Delay10ms();
			SMG_Disp(2,1);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C2 == 0)
	{
		while(C2 == 0)
		{
			SMG_Disp(1,3);
			Delay10ms();
			SMG_Disp(2,2);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C3 == 0)
	{
		while(C3 == 0)
		{
			SMG_Disp(1,3);
			Delay10ms();
			SMG_Disp(2,3);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C4 == 0)
	{
		while(C4 == 0)
		{
			SMG_Disp(1,3);
			Delay10ms();
			SMG_Disp(2,4);
			Delay10ms();
		}
				SMG_Mie();
	}
	
	R4=0;             //扫描第四行
	R1=R2=R3=1;
	C1=C2=C3=C4=1;
		if(C1 == 0)
	{
		while(C1 == 0)
		{
			SMG_Disp(1,4);
			Delay10ms();
			SMG_Disp(2,1);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C2 == 0)
	{
		while(C2 == 0)
		{
			SMG_Disp(1,4);
			Delay10ms();
			SMG_Disp(2,2);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C3 == 0)
	{
		while(C3 == 0)
		{
			SMG_Disp(1,4);
			Delay10ms();
			SMG_Disp(2,3);
			Delay10ms();
		}
				SMG_Mie();
	}
	else if(C4 == 0)
	{
		while(C4 == 0)
		{
			SMG_Disp(1,4);
			Delay10ms();
			SMG_Disp(2,4);
			Delay10ms();
		}
				SMG_Mie();
	}
	
}
void main()
{
	while(1)
	{
		ScanKeys();		
	}
}