学了矩阵式按键,感觉这方法挺不错,我之前也搜过关于一些矩阵式按键的原理以及程序,好多是找出x,y的坐标,然后通过一个计算公式计算出按键号,具体我也没仔细看,我这种方法应该是和他们不一样,今天分享给大家,大家可以做一下比较呀。
一、电路图
下面是矩阵按键的连接图。
第一行按键连接P1.0,第二行按键链接P1.1,第三行连接P1.2,第四行连接P1.3(从上到下)
第一列连接P1.4,第二列连接P1.5,第三列连接P1.6,第四列连接P1.7(从左到右)
对按键进性编序,第一行第一列的按键为0号按键,先行后列进行排序,一直到最后一个F号按键。
二、原理
第一步:P1.0–P1.3输出为0(4行),P1.4–P1.7做输入(4列)。
第二步:读取P1.4–P1.7的数据并保存。
第三步:将第二步中保存的数据从P1.4–P1.7输出,此时P1.0–P1.3做输入。
第四步:读取P1的数据,若无按键按下,此时读取的数据为0xff,若有按键按下,P1.0–P1.3中必定有一个为0(对应着被按下按键的行),P1.4–P1.7中必定有一个为0(对应着被按下按键的列)。
第五步:依据按键数组查找被按下的按键号。
举例说明:
假设0号按键被按下,P1.0–P1.3输出为0(4行),P1.4–P1.7做输入(4列),0号按键按下后,第一列对应的引脚P1.4输入为0,此时得到的P1.4–P1.7数据为0111,将0111数据从P1.4–P1.7输出,此时P1.0–P1.3做输入,由于0号按键被按下,所以P1.0输入为0,则此时P1对应的数据为0XEE(0111_0111),也就是第一行与第一列交叉处的按键被按下了。其他按键同理,不同的按键对应着不同的P1值。
三、代码部分
#include <REGX51.H>
#define SEGPORT P0
#define KEYPORT P1
typedef unsigned char u8;
typedef unsigned int u16;
//数码管显示按键号,段码
unsigned char code LEDCODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
//查找按键号的数组,行和列与电路图一致
unsigned char KEYCODE[]=
{0XEE,0XDE,0XBE,0X7E,
0XED,0XDD,0XBD,0X7D,
0XEB,0XDB,0XBB,0X7B,
0XE7,0XD7,0XB7,0X77};
//函数声明
void delayxms(u16 s); //延时函数
u8 KEY_Scan(void); //按键扫描
//主函数
void main (void)
{
while(1)
{
SEGPORT=~LEDCODE[KEY_Scan()];
}
}
void delayxms(u16 s)
{
u16 i,j;
for(i=0;i<s;i++)
{
for(j=0;j<120;j++)
{}
}
}
u8 KEY_Scan(void)
{
u8 temp,num;
KEYPORT=0xf0; //P1.0--P1.3输出0,P1.4--P1.7输出为1,为输入做准备
temp=KEYPORT; //读入P1的值
temp&=0xf0; //保留P1.4--P1.7的数据
if(temp!=0xf0) //若P1.4--P1.7输入不全为1,代表有按键被按下
{
delayxms(5); //延时消抖
KEYPORT=0xf0; //再次判断是否真有按键按下
temp=KEYPORT; //读入P1的值
temp&=0xf0; //保留P1.4--P1.7的数据
if(temp!=0xf0) //真有按键按下
{
temp|=0x0f;
KEYPORT=temp; //将读取的P1.4--P1.7数据从P1.4--P1.7输出,此时P1.0--P1.3做输入
temp=KEYPORT; //再次读取P1的值,上述原理中的第四步
for(num=0;num<16;num++) //查找按键号,
{
if(temp==KEYCODE[num])
break;
}
return num; //对应按键号
}
return 16; //表示无按键按下
}
else
return 16;
}
四、仿真
由于在家,只能用proteus进行仿真,这里当无按键按下时,我让数码管显示”-“,有按键按下时,显示被按下的按键号。
下面是我仿真的一个视频!!!
单片机矩阵按键仿真
大家有什么问题欢迎在品论区留言呀!!!
来源:oschina
链接:https://my.oschina.net/u/4347242/blog/4320776