51单片机练习:矩阵按键篇

题目:

实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时静态显示即可。(来自郭天祥老师的51单片机练习)

代码:

初始化函数:

//初始化函数
void Init()
{
	DLE = 1;
	P0 = 0x00;//关闭数码管(共阴极)段选,数码管不显示
	DLE = 0;
	
	WLE = 1;
	P0 = 0xc0;//打开所有数码管的位选
	WLE = 0;
}

延时1ms函数:

//延时1ms函数
void delay_1ms(uint z)
{
	uint x,y;
	for(x = z;x > 0;x--)
	{
		for(y =110;y > 0;y--){}
	}
}

矩阵键盘函数:

//矩阵键盘函数
void MatrixKeyboard()
{
	uchar temp;
	uint keyNum;
	P3 = 0xfe;//第一排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xee:
					keyNum = 0;
					break;
				case 0xde:
					keyNum = 1;
					break;
				case 0xbe:
					keyNum = 2;
					break;
				case 0x7e:
					keyNum = 3;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xfd;//第二排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xed:
					keyNum = 4;
					break;
				case 0xdd:
					keyNum = 5;
					break;
				case 0xbd:
					keyNum = 6;
					break;
				case 0x7d:
					keyNum = 7;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xfb;//第三排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xeb:
					keyNum = 8;
					break;
				case 0xdb:
					keyNum = 9;
					break;
				case 0xbb:
					keyNum = 10;
					break;
				case 0x7b:
					keyNum = 11;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xf7;//第四排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xe7:
					keyNum = 12;
					break;
				case 0xd7:
					keyNum = 13;
					break;
				case 0xb7:
					keyNum = 14;
					break;
				case 0x77:
					keyNum = 15;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
}

数码管显示函数:

//数码管显示函数
void display(uint keyNum)
{
	DLE = 1;
	P0 = Table[keyNum];
	DLE = 0;
	delay_1ms(5);
}

整个项目代码:

#include <reg52.h>

//【例4.2.1】实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时静态显示即可。
//晶振为 11.0529MHz

#define uint unsigned int
#define uchar unsigned char
	
sbit WLE = P2^7;//位选
sbit DLE = P2^6;//段选
//数码管的编码表
uchar code Table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void Init();
void delay_1ms(uint z);
void MatrixKeyboard();
void display(uint keyNum);

void main()
{
	Init();
	while(1)
	{
		MatrixKeyboard();
	}
}

//初始化函数
void Init()
{
	DLE = 1;
	P0 = 0x00;//关闭数码管(共阴极)段选,数码管不显示
	DLE = 0;
	
	WLE = 1;
	P0 = 0xc0;//打开所有数码管的位选
	WLE = 0;
}

//延时1ms函数
void delay_1ms(uint z)
{
	uint x,y;
	for(x = z;x > 0;x--)
	{
		for(y =110;y > 0;y--){}
	}
}

//矩阵键盘函数
void MatrixKeyboard()
{
	uchar temp;
	uint keyNum;
	P3 = 0xfe;//第一排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xee:
					keyNum = 0;
					break;
				case 0xde:
					keyNum = 1;
					break;
				case 0xbe:
					keyNum = 2;
					break;
				case 0x7e:
					keyNum = 3;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xfd;//第二排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xed:
					keyNum = 4;
					break;
				case 0xdd:
					keyNum = 5;
					break;
				case 0xbd:
					keyNum = 6;
					break;
				case 0x7d:
					keyNum = 7;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xfb;//第三排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xeb:
					keyNum = 8;
					break;
				case 0xdb:
					keyNum = 9;
					break;
				case 0xbb:
					keyNum = 10;
					break;
				case 0x7b:
					keyNum = 11;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
	P3 = 0xf7;//第四排按键
	temp = P3;
	temp = temp & 0xf0;
	while(temp != 0xf0) 
	{
		delay_1ms(10);//消抖
		temp = P3;
		temp = temp & 0xf0;
		if(temp != 0xf0)
		{
			temp = P3;
			switch(temp)
			{
				case 0xe7:
					keyNum = 12;
					break;
				case 0xd7:
					keyNum = 13;
					break;
				case 0xb7:
					keyNum = 14;
					break;
				case 0x77:
					keyNum = 15;
					break;
			}
			//等待按键释放	
			while(temp != 0xf0)
			{
				temp = P3;
				temp = temp & 0xf0;	
			}
			display(keyNum);
		}
	}
}

//数码管显示函数
void display(uint keyNum)
{
	DLE = 1;
	P0 = Table[keyNum];
	DLE = 0;
	delay_1ms(5);
}

实验板连接情况:

矩阵键盘与单片机的连接图:

心得/经验记录:

1.在处理矩阵键盘时,要巧用按位与&的使用,本实验中就时使用 P3 = 0xfe; temp = P3; temp = temp & 0xf0; 这三句话判断是否有按键按下。如果没有按键按下,P3 = 0xfe(1111 1110),它与0xf0(1111 0000)按位与之后,仍然是0xf0(1111 0000);如果有按键被按下(假如是S6被按下),那么P3 = 0xee(1110 1110),它与0xf0(1111 0000)按位与之后,结果是0xe0(1110 0000),不是0xf0(1111 0000)。此方法可以检测矩阵键盘是否有按键按下。

2.在实验的过程中,当使用的寄存器多了之后,要注意P0、P1、P3等是否会写错。

写此文章,记录自己学习51单片机过程中的一些思考和心得感悟,方便自己之后查阅,也供学习51单片机的小伙伴学习参考~

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值