五、51单片机控制矩阵按键

1、矩阵按键

1.1、矩阵按键原理分析

这里矩阵按键为4*4的矩阵按键。

(1)矩阵按键横向和纵向分割。

(2)按键两端分别接不同的IO引脚。

(3)按键物理作用不变:按下按键两端接通,弹起按键两端断开。

1.2、矩阵按键的工作过程

JP4接P3端口,JP4_8接P3^7...JP4_1接P3^0。

(1)IO端口(P3)先输出0x0f,按键列的一端为高电平,行的一端为低电平。

(2)读取P3端口引脚,若读到值不是0x0f,则说明有按键按下,判断是哪一列。

(3)P3端口再输出0xf0,按键行一端为高电平,列一端为低电平。

(4)读取P3端口引脚,若读到值不是0xf0,则说明有按键按下,判断是哪一行。

(5)结合两次行和列的位置,计算判断是哪个按键按下。

2、原理图

一般情况下JP4端口的1234或5678需要接一个电阻,不然两个IO口导通会导致短路,电流过大,这里不接是因为单片机IO口接了上拉电阻。

矩阵键盘特点:

优点:矩阵键盘省IO口。

缺点:(1)不能同时按下多个按键,例如同时按下两个按键(不再同一行,不在同一列),会检测到两个行,两个列,对应四个按键,而无法判断是其中的哪两个。(2)不能采用中断检测按键。

3、示例程序

上图中的S1~S16按键,对应1~16的数值。通过8颗LED灯,LED1~LED8表示8位二进制数,亮为1,灭为0,通过LED灯亮灭显示显示按下按键的数值。LDE1为低位,LED8为高位。

#include <reg52.h>


/*实现功能
 *S1~S16按键,对应1~16的数值。
 *LED1~LED8表示8位二进制数,亮为1,灭为0。
 *通过LED灯亮灭显示显示按下按键的数值。
 *LDE1为低位,LED8为高位。
 */

/*硬件连接
 *LED接P0端口,LED1接P0^0、LED2接P0^1...LED8接P0^7。
 *矩阵按键接P3端口,JP4_8接P3^7...JP4_1接P3^0。
 *LED灯为共阴极,高电平点亮。
 */
#define LED P0
#define KEY P3


/*函数声明*/
unsigned char GetKeyValue();   /*获取键值*/ 
void Delay15ms();


void main(void)
{
	unsigned char KeyValue = 0;
	LED = 0x00; 			/*默认所有LED灯熄灭*/
	
	while(1)
	{
		KeyValue = GetKeyValue();
		if(KeyValue != 0)
            LED = KeyValue;
	}
}


unsigned char GetKeyValue()
{
	unsigned char hang = 0;
	unsigned char lie = 0;
	unsigned char KeyValue = 0;
	
	/*检测列*/
	KEY = 0x0f;  
	if(KEY != 0x0f)      /*说明有按键按下*/
	{
		Delay15ms();     /*消抖,等待电平稳定*/							
		switch(KEY)
		{
			case 0x0e: lie = 4; break;    /*第4列有按键按下*/	
			case 0x0d: lie = 3; break;    /*第3列有按键按下*/
			case 0x0b: lie = 2; break;    /*第2列有按键按下*/	
			case 0x07: lie = 1; break;    /*第1列有按键按下*/	
			default:   lie = 0; break;
		}
	}
		
	/*检测行*/
	KEY = 0xf0;          /*从IO口输出*/
	if(KEY != 0xf0)      /*读IO口,说明有按键按下*/
	{
		switch(KEY)
		{
			case 0x70: hang = 1; break;    /*第1行有按键按下*/
			case 0xb0: hang = 2; break;    /*第2列有按键按下*/
			case 0xd0: hang = 3; break;    /*第3列有按键按下*/
			case 0xe0: hang = 4; break;    /*第4列有按键按下*/	
			default:   hang = 0; break;		
		}
	}
		
	if(hang !=0 && lie !=0)
	{
		KeyValue = (hang-1)*4 +lie;
		return KeyValue;
	}
	
	return 0;     /*表示没有程序按下或有多个按键同时按下*/
}


void Delay15ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 30;
	j = 43;
	do
	{
		while (--j);
	} while (--i);
}









  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码织梦师小猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值