C51矩阵按键

矩阵按键_行列式扫描

1.常用扫描方法

行列式:
先送一列为低电平,其余几列全为高电平(此时我们确
定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的,用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键,当有键被按下时便可判断出按下的键是哪一个键。
当然我们也可以将行线置低电平,扫描列是否有低电平。从而达到整个键盘的检测。

线翻转:
就是使所有行线为低电平时,检测所有列线是否有低电平,如果
有,就记录列线值;然后再翻转,使所有列线都为低电平,检测所有行线的值,由于有按键按下,行线的值也会有变化,记录行线的值。

2.原理图
在这里插入图片描述3.行列式扫描
例:
第一行 P17 1 0
第二行 P16 1 1
第三行 P15 1 1
第四行 P14 1 1
第一列 P13 0 0
第二列 P12 1 1
第三列 P11 1 1
第四列 P10 1 1

第一列输入低电平 1111 0111 :0xf7
按键1按下: 0111 0111 : 0x77
按键5按下: 1011 0111: 0xb7
按键9按下: 1101 0111: 0xd7
按键13按下:1110 0111:0xe7

第二列输入低电平 1111 0111 :0xfb
按键2按下: 0111 1011 : 0x7b
按键6按下: 1011 1011: 0xbb
按键10按下: 1101 1011: 0xdb
按键14按下:1110 1011:0xeb

第三列输入低电平 1111 0111 :0xfd
按键3按下: 0111 1101 : 0x7d
按键7按下: 1011 1101: 0xbd
按键11按下: 1101 1101: 0xdd
按键15按下:1110 1101:0xed

第四列输入低电平 1111 0111 :0xfe
按键4按下: 0111 1110: 0x7e
按键8按下: 1011 1110: 0xbe
按键12按下: 1101 1110: 0xde
按键16按下:1110 1110:0xee

3.软件设计
在这里插入图片描述4.软件编码
#include <REGX51.H>

typedef unsigned char u8;
typedef unsigned int u16;

#define KEY_MATRIX_PORT P1
#define SMG_A_DP_PORT P0

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,};

void delay_10us(u16 ten_us)
{
while(ten_us–);
}

u8 key_matrix_ranks_scan(void)
{
u8 key_value=0;

KEY_MATRIX_PORT=0xf7;//第一列为低电平
if(KEY_MATRIX_PORT!=0xf7)
{	
	delay_10us(1000);//消抖
	switch(KEY_MATRIX_PORT)
	{
		case 0x77:key_value=1;break;
		case 0xb7:key_value=5;break;
		case 0xd7:key_value=9;break;
		case 0xe7:key_value=13;break;
	}
}
	while(KEY_MATRIX_PORT!=0xf7);//等待按键松开
	

KEY_MATRIX_PORT=0xfb;//第二列为低电平
if(KEY_MATRIX_PORT!=0xfb)
{	
	delay_10us(1000);//消抖
	switch(KEY_MATRIX_PORT)
	{
		case 0x7b:key_value=2;break;
		case 0xbb:key_value=6;break;
		case 0xdb:key_value=10;break;
		case 0xeb:key_value=14;break;
	}
}
	while(KEY_MATRIX_PORT!=0xfb);//等待按键松开


KEY_MATRIX_PORT=0xfd;//第三列为低电平
if(KEY_MATRIX_PORT!=0xfd)
{	
	delay_10us(1000);//消抖
	switch(KEY_MATRIX_PORT)
	{
		case 0x7d:key_value=3;break;
		case 0xbd:key_value=7;break;
		case 0xdd:key_value=11;break;
		case 0xed:key_value=15;break;
	}
}
	while(KEY_MATRIX_PORT!=0xfd);//等待按键松开


KEY_MATRIX_PORT=0xfe;//第四列为低电平
if(KEY_MATRIX_PORT!=0xfe)
{	
	delay_10us(1000);//消抖
	switch(KEY_MATRIX_PORT)
	{
		case 0x7e:key_value=4;break;
		case 0xbe:key_value=8;break;
		case 0xde:key_value=12;break;
		case 0xee:key_value=16;break;
	}
}
	while(KEY_MATRIX_PORT!=0xfe);//等待按键松开

	return key_value;//返回键值

}

void main()
{
u8 key=0;//定义变量
while(1)
{
key=key_matrix_ranks_scan();
if(key!=0)
SMG_A_DP_PORT=gsmg_code[key-1];
//在程序里0代表第一个1代表第二个

}

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值