按键
简介
本篇博客,主要介绍一种新的蓝桥杯按键写法
按键采集
该按键的思路,是将所有按键的状态一次性采集到一个变量中存起来,然后对每一个按键进行状态判断。
首先,写一个按键采集函数
独立按键
//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函数中调用的,在使用按键时,只需用查询函数在主函数中查询按键,即可实现按键操作