51单片机(矩阵键盘)基于51STC15F2K61S2系列

矩阵键盘

矩阵键盘原理图

在这里插入图片描述

开发板设置:

J13跳线帽:IO模式

J5跳线帽:KBD模式(矩阵键盘模式) --> KBD模式是将上述的一、二引脚相连接

矩阵键盘与LED灯及数码管的结合使用:

//1、使用矩阵键盘的方式点击S7键盘后第一个数码管显示7,点击S6键盘后第二个数码管显示6,点击S5键盘后第三个数码管显示5,点击S4键盘后第4个数码管显示4.
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8;
uchar one, two, three, four, five, six, seven, eight;
uchar P30_flag = 0, P31_flag = 0, P32_flag = 0, P33_flag = 0;
void keypad();
void delay_tm(uint ms);
void SEG_open(one, two, three, four, five, six, seven, eight);
void main()
{
	P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
	P44 = 0;	//将P44引脚设置为低电位  需要哪一列亮时就将哪一列的引脚电位赋值为低电位。
	while(1){
		keypad();
		if(P30_flag == 1){
			P30_flag = 0;
			SEG1 = 7;
		}
		if(P31_flag == 1){
			P31_flag = 0;
			SEG2 = 6;
		}
		if(P32_flag == 1){
			P32_flag = 0;
			SEG3 = 5;
		}
		if(P33_flag == 1){
			P33_flag = 0;
			SEG4 = 4;
		}
		SEG_open(SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8);
	}
}
void keypad()			//判断键盘是否按下
{
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			P30_flag = 1;
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			P31_flag = 1;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			P32_flag = 1;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			P33_flag = 1;
		while(!P33);
	}
}
void delay_tm(uint ms)	
{
	uint i, j;
	for(i = 0; i < 853 ; i++)
		for(j = 0; j < ms; j++);
}
void SEG_open(one, two, three, four, five, six, seven, eight)//点亮数码管程序
{
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = tab[one];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X02; P2 = 0XFF; P0 = tab[two];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X04; P2 = 0XFF; P0 = tab[three];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X08; P2 = 0XFF; P0 = tab[four];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X10; P2 = 0XFF; P0 = tab[five];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X20; P2 = 0XFF; P0 = tab[six];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X40; P2 = 0XFF; P0 = tab[seven];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X80; P2 = 0XFF; P0 = tab[eight];
	delay_tm(1);
	P0 = 0XFF;
}

//2、将矩阵键盘前两列所对应的数字依次显示到数码管屏幕上
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8;
uchar one, two, three, four, five, six, seven, eight;
uchar S7_flag = 0, S6_flag = 0, S5_flag = 0, S4_flag = 0, S11_flag = 0, S10_flag = 0, S9_flag = 0, S8_flag = 0;//使用标志位,方便后续使用。
void keypad();
void delay_tm(uint ms);
void SEG_open(one, two, three, four, five, six, seven, eight);
void main()
{
	P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
	while(1){
		keypad();
		if(S7_flag == 1){
			S7_flag = 0;
			SEG1 = 7;
		}
		if(S6_flag == 1){
			S6_flag = 0;
			SEG2 = 6;
		}
		if(S5_flag == 1){
			S5_flag = 0;
			SEG3 = 5;
		}
		if(S4_flag == 1){
			S4_flag = 0;
			SEG4 = 4;
		}
		if(S11_flag == 1){
			S11_flag = 0;
			SEG5 = 11;
		}
		if(S10_flag == 1){
			S10_flag = 0;
			SEG6 = 10;
		}
		if(S9_flag == 1){
			S9_flag = 0;
			SEG7 = 9;
		}
		if(S8_flag == 1){
			S8_flag = 0;
			SEG8 = 8;
		}
		SEG_open(SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8);
	}
}
void keypad()
{
	P44 = 0; P42 = 1;		//当使用第二一列的数码管时,将P44引脚赋值为低电位
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			S7_flag = 1;
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			S6_flag = 1;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			S5_flag = 1;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			S4_flag = 1;
		while(!P33);
	}
	
	P44 = 1; P42 = 0;		//当使用第二列的数码管时,将P42引脚赋值为低电位
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			S11_flag = 1;
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			S10_flag = 1;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			S9_flag = 1;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			S8_flag = 1;
		while(!P33);
	}
}
void delay_tm(uint ms)
{
	uint i, j;
	for(i = 0; i < 853 ; i++)
		for(j = 0; j < ms; j++);
}
void SEG_open(one, two, three, four, five, six, seven, eight)
{
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = tab[one];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X02; P2 = 0XFF; P0 = tab[two];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X04; P2 = 0XFF; P0 = tab[three];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X08; P2 = 0XFF; P0 = tab[four];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X10; P2 = 0XFF; P0 = tab[five];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X20; P2 = 0XFF; P0 = tab[six];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X40; P2 = 0XFF; P0 = tab[seven];
	delay_tm(1);
	P0 = 0XFF;
	P2 = 0XC0; P0 = 0X80; P2 = 0XFF; P0 = tab[eight];
	delay_tm(1);
	P0 = 0XFF;
}

//3、使用第一、第二列矩阵程序按下S7、S6、S5、S4、S11、S10、S9、S8按键,依次用第一个数码管显示1、2、3、4、5、6、7、8数值。
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar key_change = 0;
void keypad();
void delay_tm(uint ms);
void main()
{
	P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
	while(1)
	{
		keypad();
		if(!key_change == 0){		//使用key_change对P0的数值进行交换,使得P0可以直接显示出所按键盘对应的数字。
			P0 = tab[key_change];
			key_change = 0;
		}
	}
}
void keypad()
{
	P44 = 0; P42 = 1;
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			key_change = 1;			//将需要的数值赋值给key_change,以便主程序使用。以下key_change均为该原因。
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			key_change = 2;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			key_change = 3;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			key_change = 4;
		while(!P33);
	}
	
	P44 = 1; P42 = 0;
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			key_change = 5;
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			key_change = 6;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			key_change = 7;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			key_change = 8;
		while(!P33);
	}
}
void delay_tm(uint ms)
{
	uint i, j;
	for(i = 0; i < 853 ; i++)
		for(j = 0; j < ms; j++);
}

//4、使用矩阵键盘当 按下S4时LED灯全部亮;按下S5时LED灯全部灭;按下S6时LED奇数灯亮;按下S7时LED偶数灯亮。
#include<stc15.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar S7_flag = 0,S6_flag = 0,S5_flag = 0,S4_flag = 0;
void keypad();
void delay_tm(uint ms);
void main()
{
	P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
	while(1){
		keypad();
		if(S7_flag == 1){
			S7_flag = 0;
			P0 = 0X55;
		}
		if(S6_flag == 1){
			S6_flag = 0;
			P0 = 0XAA;
		}
		if(S5_flag == 1){
			S5_flag = 0;
			P0 = 0XFF;
		}
		if(S4_flag == 1){
			S4_flag = 0;
			P0 = 0X00;
		}
	}
}

void keypad()
{
	P44 = 0;
	if(P30 == 0){
		delay_tm(10);
		if(P30 == 0)
			S7_flag = 1;
		while(!P30);
	}
	if(P31 == 0){
		delay_tm(10);
		if(P31 == 0)
			S6_flag = 1;
		while(!P31);
	}
	if(P32 == 0){
		delay_tm(10);
		if(P32 == 0)
			S5_flag = 1;
		while(!P32);
	}
	if(P33 == 0){
		delay_tm(10);
		if(P33 == 0)
			S4_flag = 1;
		while(!P33);
	}
}
void delay_tm(uint ms)	
{
	uint i, j;
	for(i = 0; i < 853 ; i++)
		for(j = 0; j < ms; j++);
}

//使用矩阵键盘按下S4-S16键盘依次显示1-9(按照列扫描的方法进行)
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar key_change = 0;		//标志位:用来记录数码管将要显示的数字
void keypad();
void delay_tm(uint ms);
void main()
{
	P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
	P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
	while(1){
		keypad();
		if(key_change != 0){
			P0 = tab[key_change];		//将tab表格中第key_change个值赋给P0,即将第key_change个数在数码管上进行显示
			key_change = 0;
		}
	}
}
void keypad()
{
	uint temp;			//定义中间变量,将后续P3的值赋值个temp中间变量
	P44 = 0;  P3 = 0X7F; //0111 1111 P42 = 1;//
	temp = P3;
	temp = temp&0X0F;	//意思为temp = P3&0X0F
	if(temp != 0X0F){	//判断P3是否等于0X0F
		delay_tm(10);
		//temp = P3;
		//temp = temp&0X0F;				//这两处可以省略
		if(temp != 0X0F){ //0000 1111
			temp = P3;
			switch(temp){		//此处switch中的参数为temp而不是P3是为了后续方便退出循环
				case 0X7E :key_change = 1; break; //0111 1110
				case 0X7D :key_change = 2; break;	//0111 1101
				case 0X7B :key_change = 3; break;	//0111 1011
				case 0X77 :key_change = 4; break;	//0111 0111
				default : break;
			}	
			while(temp != 0X0F){		//当P3=0X0F时退出循环,即当按键松开时退出循环
				temp = P3;
				temp = temp&0X0F;
			}
		}
	}
	P44 = 1;  P42 = 0; P3 = 0XBF; //1011 1111 P42 = 1; //将串口连接至P42串口
	temp = P3;
	temp = temp&0X0F;
	if(temp != 0X0F){
		delay_tm(10);
		//temp = P3;
		//temp = temp&0X0F;				//这两处可以省略
		if(temp != 0X0F){ //0000 1111
			temp = P3;
			switch(temp){
				case 0XBE :key_change = 5; break; //1011 1110
				case 0XBD :key_change = 6; break;	//1011 1101
				case 0XBB :key_change = 7; break;	//1011 1011
				case 0XB7 :key_change = 8; break;	//1011 0111
				default : break;
			}	
			while(temp != 0X0F){
				temp = P3;
				temp = temp&0X0F;
			}
		}
	}
	P44 = 1;  P42 = 1; P3 = 0XDF; //1101 1111 P42 = 1;//此处代码中的P44 = 1;  P42 = 1;不可以省略,省略后会出现bug
	temp = P3;
	temp = temp&0X0F;
	if(temp != 0X0F){
		delay_tm(10);
		//temp = P3;
		//temp = temp&0X0F;				//这两处可以省略
		if(temp != 0X0F){ //0000 1111
			temp = P3;
			switch(temp){
				case 0XDE :key_change = 9; break; //1101 1110
				case 0XDD :key_change = 10; break;	//1101 1101
				case 0XDB :key_change = 11; break;	//1101 1011
				case 0XD7 :key_change = 1; break;	//1101 0111
				default : break;
			}	
			while(temp != 0X0F){
				temp = P3;
				temp = temp&0X0F;
			}
		}
	}
	P44 = 1;  P42 = 1; P3 = 0XEF; //1110 1111 P42 = 1;
	temp = P3;
	temp = temp&0X0F;
	if(temp != 0X0F){
		delay_tm(10);
		//temp = P3;
		//temp = temp&0X0F;				//这两处可以省略
		if(temp != 0X0F){ //0000 1111
			temp = P3;
			switch(temp){
				case 0XEE :key_change = 2; break; //1110 1110
				case 0XED :key_change = 3; break;	//1110 1101
				case 0XEB :key_change = 4; break;	//1110 1011
				case 0XE7 :key_change = 5; break;	//1110 0111
				default : break;
			}	
			while(temp != 0X0F){
				temp = P3;
				temp = temp&0X0F;
			}
		}
	}
}
void delay_tm(uint ms)
{
	uint i, j;
	for(i = 0; i < 853 ; i++)
		for(j = 0; j < ms; j++);
}
  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值