蓝桥杯长短按键

按键

简介

本篇博客,主要介绍一种新的蓝桥杯按键写法

按键采集

该按键的思路,是将所有按键的状态一次性采集到一个变量中存起来,然后对每一个按键进行状态判断。
首先,写一个按键采集函数

独立按键

//key_dat是一个用来存储按键值的一个8bit的全局变量
void get_key()		//获取按键值
{
	key_dat = P3&0x0f;
}

在key_dat中,3-0位分别对应着按键S4-S7

矩阵按键

//x(i)是矩阵按键的列
//key_dat是一个用来存储按键值的一个16bit的全局变量
void get_key()		//获取按键值
{
	x1 = 0;
	x2 = x3 = x4 = 1;
	key_dat = key_dat << 4 | (P3&0x0f);
	
	x2 = 0;
	x1 = x3 = x4 = 1;
	key_dat = key_dat << 4 | (P3&0x0f);
	
	x3 = 0;
	x2 = x1 = x4 = 1;
	key_dat = key_dat << 4 | (P3&0x0f);
	
	x4 = 0;
	x2 = x3 = x1 = 1;
	key_dat = key_dat << 4 | (P3&0x0f);
}

在key_dat中,15-0位分别对应着按键S4-S19

长短按键判断(按键状态机)

定义两个数组,一个用来记录按键的状态,一个用来记录按键按下时间

此处代码为矩阵按键代码,独立按键与矩阵按键类似

static uint8 key_state[16];		//按键状态
static uint8 key_t[16];			//按键计时

void key_server()
{
	uint8 i = 0;
	get_key();		//获取按键值
	for(i = 0;i<16;i++)		//从0-16,依次处理S19-S4按键
	{
		switch(key_state[i])		//判断当前按键状态
		{
			case 0:		//未按下
				if(!(key_dat & (1<<i)))		
				/*按键按下时,key_dat对应位为0,例如我们要检测S4按键,S4对应的i为15;
				当所有按键都没有按下时,key_dat = 11111111b,1<<15 = 10000000b,key_dat & 1<<15 = 10000000b,输出为128,取反为0;
				当S4按下时,key_dat = 01111111b,key_dat & 1<<15 = 00000000b,输出为0,取反为1。
				*/
				{
					key_state[i] = 1;		//确认按下,进入下一阶段
				}
				break;
			case 1:		//按下时
				if(!(key_dat & (1<<i)))
				{
					key_t[i]++;		//按键计时
				}
				else
				{
					key_state[i] = 0;
					if(key_t[i] < 25) 		key_t[i] = 0;		//未按(未过消抖)
					else if(key_t[i] < 500) key_state[i] = 2;	//短按
					else 					key_state[i] = 3;	//长按
				}
				break;
		}
	}
}

按键查询函数

按键枚举

typedef enum{
	S19 = 0,S18,S17,S16,
	S15 = 4,S14,S13,S12,
	S11 = 8,S10,S9,S8,
	S7 = 12,S6,S5,S4
}E_KEY;

按键查询函数

//短按查询函数(短按返回1)
bit onShortPress(E_KEY key_code)
{
	if(key_state[key_code] == 2)
	{
		key_state[key_code] = 0;
		return 1;
	}
	return 0;
}

//长按查询函数(长按返回1)
bit onLongPress(E_KEY key_code)
{
	if(key_state[key_code] == 3)
	{
		key_state[key_code] = 0;
		return 1;
	}
	return 0;
}

//按下查询函数(长短按键按下都会返回1)
bit onClick(E_KEY key_code)
{
	if(key_state[key_code] == 2 || key_state[key_code] == 3)
	{
		key_state[key_code] = 0;
		return 1;
	}
	return 0;
}

示例代码

//如果S4按下,对mode取反
//如果S5按下,对display取反
if(onClick(S4))
{
	mode = !mode;
}
if(onClick(S5))
{
	display = !display;
}

[1]跟按键相关的代码都放在按键文件中,key_server函数放在定时器中,用于按键监听
[2]示例代码是在main函数中调用的,在使用按键时,只需用查询函数在主函数中查询按键,即可实现按键操作

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值