主函数部分,其中的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,也不易改变输出电平,检测更为准确