我们在使用按键时,可能会碰到按下检测,弹起检测以及一直按下实现特定功能(如:一直按下,使值间隔自增)。
下面是使用状态机的键值检测函数,只需将函数放入while中大概20ms运行一次即可,使用时先判断对应标志位是否为1,在判断具体键值,例如:
if (m4x4_press_flag == 1)
{
switch (m4x4_press_value)
{
case matrix_4x4_key_s1:······;break;
case matrix_4x4_key_s2:······;break;
·······
}
}//要注意的是用完后要标志位要清0,因为键值是不变的也是不能软件该变的,否则会出错。
//获取参数定义
//按键键值获取
unsigned char m4x4_now_value = 0xff; //按键实时值
unsigned char m4x4_press_value = 0xff; //按键按下响应值
unsigned char m4x4_upspring_value = 0xff; //按键弹起响应值
unsigned char m4x4_continued_value = 0xff; //按键持续响应值
unsigned char m4x4_press_flag = 1; //按键按下标志
unsigned char m4x4_upspring_flag = 1; //按键弹起标志
unsigned char m4x4_continued_flag = 1; //按键持续标志
unsigned char m4x4_continued_mode = 0; //持续响应模式(为0是按下就响应一次,x为1是等待一定间隔后响应))
unsigned char m4x4_continued_xms = 50; //按键持续响应的间隔(大小为key_continued_xms*key_readtimexms ms)
//按键键值获取
void read_matrix_4x4_val()
{
#define _have_press_start 1 //按下状态
#define _no_press_start 0 //非按下状态
#define continued_delay 1 //等待一定间隔后响应状态
#define continued_no_delay 0 //按下就响应状态
static unsigned char matrix_last_key_value = matrix_4x4_key_no, _press_flag = 0, _count = 0, first = 0; //_count是一个间接计数器,为持续响应提供间隔时钟,可替换为其他计数器
m4x4_now_value = read_matrix_4x4();
if (matrix_last_key_value != m4x4_now_value) //按下检测
{
m4x4_press_value = m4x4_now_value;
m4x4_press_flag = 1; //按键按下标志置1表示有按键按下
m4x4_upspring_flag = 0; //清除按键弹起标志
m4x4_continued_flag = 0; //清除按键持续标志
_press_flag = _have_press_start; //按下标志位置为按下状态
_count = 0; //间接计数器清0
first = 0;
}
if ((m4x4_now_value == matrix_4x4_key_no) && (_press_flag == _have_press_start)) //弹起检测
{
m4x4_upspring_value = matrix_last_key_value;
m4x4_press_flag = 0; //清除按键按下标志
m4x4_upspring_flag = 1; //按键弹起标志置1表示有按键正弹起
m4x4_continued_flag = 0; //清除按键持续标志
_press_flag = _no_press_start; //按下标志位置为非按下状态
}
if ((_press_flag == 1) && (matrix_last_key_value == m4x4_now_value)) //处于按下状态且键值未变(变了会在进函数进入第一条判断语句)
{
if (m4x4_continued_mode == continued_no_delay) //持续按下且按下就响应状态
{
if (first == 0) //第一次按下
{
m4x4_continued_value = matrix_last_key_value;
_count = 0;
}
else if (_count == m4x4_continued_xms)
{
m4x4_continued_value = matrix_last_key_value;
_count = 0; //间接计数器清0
}
}
else //持续按下且等待一定间隔后响应状态
{
if (_count == m4x4_continued_xms)
{
m4x4_continued_value = matrix_last_key_value;
_count = 0;
}
}
_count++; //计数值自加
}
matrix_last_key_value = m4x4_now_value;
}