Bootstrap

矩阵键盘控制LCD1602显示屏显示数字

 主函数部分,其中的LCD1602.h的头文件是在哔哩哔哩江科大自化协的博主的视频资料

#include <REGX51.H>
#include"LCD1602.h"

void Delay(int time)
unsigned char test(void);
unsigned char keynumber;
//int keynumber;

void main(void)
{
	keynumber = 0;
	LCD_Init();
	LCD_ShowString(1,1,"Hello,World!");
	while(1)
	{
		keynumber = test();//获取按下的按键数字
		if(keynumber)
		{
			LCD_ShowNum(2,1,keynumber,2);
		}
	}
}
void Delay(int time)		//延时函数(单位 毫秒)1 秒 = 1 毫秒
{
	unsigned char i, j;

	time = 2;//偷懒,就不需要一个一个的将20改为2了
	i = 2;
	j = 199;
	while(time--)
	{
	do
	{
		while (--j);
	} while (--i);
  }
	
}

unsigned char test(void)
{
	//while(1)
	{
	unsigned char Keynumber;
	Keynumber = 0;
	P0 = 0xFF;
	P0_4 = 0;//第一列置0
	//检测行
	if(P0_0 == 0)
	{
		Delay(1);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(1);//再次消抖
		Keynumber = 1;
	}
		//return Keynumber;
		if(P0_1 == 0)
	{
		Delay(1);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(1);//再次消抖
		Keynumber = 5;
	}
	if(P0_2 == 0)
	{
		Delay(1);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(1);//再次消抖
		Keynumber = 9;
	}
	if(P0_3 == 0)
	{
		Delay(1);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(1);//再次消抖
		Keynumber = 13;
	}
	//第一列检测完成
	
	//检测第二列
	P0 = 0xFF;
	P0_5 = 0;//第二列置0
	//检测行
	if(P0_0 == 0)
	{
		Delay(1);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(1);//再次消抖
		Keynumber = 2;
	}
	if(P0_1 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 6;
	}
	if(P0_2 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 10;
	}
	if(P0_3 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 14;
	}
	//第二列检测完成
	//检测第三列
	P0 = 0xFF;
	P0_6 = 0;//第三列置0
	//检测行
	if(P0_0 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 3;
	}
	if(P0_1 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 7;
	}
	if(P0_2 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 11;
	}
	if(P0_3 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 15;
	}
	//第三列检测完成
	//检测第四列
	P0 = 0xFF;
	P0_7 = 0;//第四列置0
	//检测行
	if(P0_0 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 4;
	}
	if(P0_1 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 8;
	}
	if(P0_2 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 12;
	}
	if(P0_3 == 0)
	{
		Delay(20);//消抖
		while(P0_0 == 0)//检测按键是否还是按下状态
		{
			
		}//松手后跳出
		Delay(20);//再次消抖
		Keynumber = 16;
	}
		return Keynumber;
  }
}

总结:

    首先是我学习时遇到的问题:

在我一开始运行的时候出现的问题就是,一开始在给主函数的keynumber赋值的时候,等号的左值是叫做Matrixkey的函数,当我按下1按键时显示屏显示01,但是当我按下其他按键时,显示屏没有任何反应,一开始我也不明白是哪里错了,然后我重新创建了一个新的函数test,目的是将Matrixkey函数分成小部分,即按照一个按键的一个按键的逐一搬运到test函数,搬运第一个按键的时候就直接烧录,然后测试是哪一部分出的问题,我先搬运的是1和2,都没问题,于是我直接搬运了一整行,发现仍然没问题,直到我开始搬运第二行,有问题了,就是按下第一个,然后很快的就按下第二行的某个按键的时候,第二个数字没有马上显示,而是间隔了一段相对长的时间,当时想的是没出错就行,于是就继续做cv的工作,全部搬运完开始运行时,出现第二个问题,乱码,我当时想到的是延时的问题,于是就把延时的次数改成了time = 2,因此我的主函数虽然还是20,但是因为我偷懒,还是直接在Delay的内部给time赋值为2,然后问题就解决了,所以大概率是因为,按下第一个按键,再按下第二个按键后,第一个按键显示还没结束,就显示了第二个

    其次是我后面通过矩阵扫面明白的一个问题:

就是为什么这里在扫描时是将全部io口置1,然后在将要扫描的行置0,而不是前者置0后者置1,当然两种方法在做简单的程序的时候都是可行的,但是第一种更准确,51单片机的io口是双向输出输入的模式,采用的是若上拉输出(当输出的是高电平时,能够输出的电流很小,很容易被别的强下拉拉低),假设下列情况:

 

情况一:

将所有io口置0,然后将要检测行置1,若按下按键1,有可能被置1的行会被拉低为0,所有的io口又变为了0,那就检测不到了,这是我个人的看法

情况二:

将所有io口置1,然后将要检测行置0,若按下按键1,也不易改变输出电平,检测更为准确

;