51单片机——矩阵按键逐行扫描短按长按一直按方案1.2

1、删减了《51单片机——独立按键、矩阵按键多种方案1.1》里的一些不怎么用的代码。

2、添加了逐行扫描按键(需要定时器20毫秒配合使用)。

3、支持按键短按、长按、一直按,代码里只做了短按处理,如要处理长按和一直按只需添加相应的代码即可。

4、按键处理我只点亮led灯了,需要其它功能自行添加即可。

5、最大优化我觉得是没有一个delay延迟。

备注:按键处理及按键扫描放入定时器中断里即可。

#ifndef __KEY2_H__
#define __KEY2_H__

extern void key_hang(void);//按键行扫描,需要配合定时器
extern void key_process(void);//处理按键对应的结果

#endif //!__KEY2_H__
#include "REG52.H"
#include "led.h"
#define hang P3

//矩阵按键真值表4行*4列判断是哪个按键被按下
static unsigned char code key_true[4][4] = {
									1,	2,	3,	4,
									5,  6,  7,  8,
									9,  10,	11,	12,
									13, 14,	15,	16
};

void key_hang(void)//按键行扫描,建议20毫秒扫一下
{
	static unsigned char i = 0;
	i++;
	switch (i)//共计4行,低电平扫描
	{
	case 1:hang = 0xfe;break;
	case 2:hang = 0xfd;break;
	case 3:hang = 0xfb;break;
	case 4:hang = 0xf7;i = 0;break;
	default:hang = 0xff;i = 0;
		break;
	}
}

static unsigned char key16_3(void)//每隔10毫秒30毫秒50毫秒.....进来一次
{
	static unsigned char key_time = 9;//按键次数或时间初值为9
	static unsigned char hang_true =0;
	static unsigned char lie_true = 0;
	//if (Time_20ms == 1)//如果20ms时间到的话就开始判断是否有按键按下
	//{
		if ((hang & 0xf0) != 0xf0)//如果有按键按下
		{
			hang_true = hang & 0x0f;//计算4行的当前值
			lie_true = hang & 0xf0;//计算4列的当前值
			key_time++;//当有按键被按下,key_time++一次时间就加20毫秒,第一次++的时候时间记为0毫秒
			if (key_time < 5)	--key_time;//避免数据加的太多溢出,防止用户一直按
			if (key_time > 150)//表示长按且大于3000毫秒
			{
				//如果有按键按了3秒以上,在这里先不处理这么久的
				key_time = 9;//恢复初始值
				return 0;
			}
			return 0;
		}
		else//判断一下当前按键值是否为短按
			if (10 < key_time < 150)//表示短按且时间大于100毫秒小于3秒
			{
				switch (hang_true)
				{
				case 0x0e:hang_true = 0;break;
				case 0x0d:hang_true = 1;break;
				case 0x0b:hang_true = 2;break;
				case 0x07:hang_true = 3;break;
				default:
					break;
				}
				switch (lie_true)
				{
					case 0xe0:lie_true = 0;break;
					case 0xd0:lie_true = 1;break;
					case 0xb0:lie_true = 2;break;
					case 0x70:lie_true = 3;break;
				default:
					break;
				}
				key_time = 9;//恢复初始值,好进行下次按键判断
				return key_true[hang_true][lie_true];
			}
			return 0;
	//}
	//return 0;
}
void key_process(void)//处理按键对应的方法
{
	switch (key16_3())
	{
	case 0:		break;//默认没有按键按下将会返回0
	case 1:		LED_Admin_EN(0x7f);break;//led灯从左到右亮
	case 2:		LED_Admin_EN(0xbf);break;
	case 3:		LED_Admin_EN(0xdf);break;
	case 4:		LED_Admin_EN(0xef);break;
	case 5:		LED_Admin_EN(0xf7);break;
	case 6:		LED_Admin_EN(0xfb);break;
	case 7:		LED_Admin_EN(0xfd);break;
	case 8:		LED_Admin_EN(0xfe);break;//led灯从左到右亮
	case 9:		LED_Admin_EN(0xfe);break;//led灯从右到左亮
	case 10:	LED_Admin_EN(0xfd);break;
	case 11:	LED_Admin_EN(0xfb);break;
	case 12:	LED_Admin_EN(0xf7);break;
	case 13:	LED_Admin_EN(0xef);break;
	case 14:	LED_Admin_EN(0xdf);break;
	case 15:	LED_Admin_EN(0xbf);break;
	case 16:	LED_Admin_EN(0x7f);break;//led灯从右到左亮
	default:
		break;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

金丝草

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

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

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

打赏作者

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

抵扣说明:

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

余额充值