搜索
写经验 领红包

一个功能丰富的按键扫描的程序是什么(一个功能丰富的按键扫描的程序叫什么)

导语:一个功能丰富的按键扫描的程序

一个功能丰富的按键扫描的程序是什么(一个功能丰富的按键扫描的程序叫什么)

作为一个嵌入式工程师,经常会和按键打交道。按键一般分为2大类,一类是可恢复按键,例如轻触开关,松开后会自动弹回;另一类为不可恢复按键,例如拨动开关,拨到哪边,就固定在那边。

按键的行为,一般为按下,松开,长按和长按后的松开,有时也需对一些特别的行为做检测,例如在一段时间内按下的次数,长按并计算长按的时间,在一段时间按下一定次数并且在最后一次长按住,等等。现在就分享一个按键扫描程序,同时适用可恢复按键和不可恢复按键,并且可检测上面提到的按键行为。但这个程序有一个缺点就是只能分辨一个按键,即多个按键同时按下时只会检测到优先级高的按键。

概括的流程图如图1

详细的程序如下:

获取按键状态:define HAL_KEY_SW_MASK_BIT 0xff

uint8 u8KeyDIOState = (HAL_KEY_SW_PORT&HAL_KEY_SW_MASK_BIT);

其中可以根据自己的需要修改上面两个宏定义,例如需要用到P1口,则修改宏定义

define HAL_KEY_SW_MASK_BIT 0x81。

进行按键消抖:

for (i = 0; i < 8; i++)

{

uint8 u8Key = ((u8KeyDIOState >> i) & 1);

s_u8KeyDebounce[i] <<= 1;

s_u8KeyDebounce[i] |= u8Key;

if ((0 == s_u8KeyDebounce[i]) && ((s_u8KeyState[i] == FALSE)||(s_u8_KeyStateInit[i] == FALSE)))

{

s_u8_KeyStateInit[i] = TRUE;

s_u8KeyState[i] = TRUE;

keyAttribute.keys = i;

keyAttribute.behavior = HAL_KEY_PRESS_DOWN;

keyAttribute.numattribute = 0;

keyAttribute.timeattribute = 0;

(pHalKeyProcessFunction) (&keyAttribute);

endif

endif

endif

}

else if ((0xff == s_u8KeyDebounce[i]) && ((s_u8KeyState[i] == TRUE)||(s_u8_KeyStateInit[i] == FALSE)))

{

s_u8_KeyStateInit[i] = TRUE;

s_u8KeyState[i] = FALSE;

keyAttribute.keys = i;

keyAttribute.behavior = HAL_KEY_PRESS_UP;

keyAttribute.numattribute = 0;

keyAttribute.timeattribute = 0;

(pHalKeyProcessFunction) (&keyAttribute);

if define ENABLE_MULTIPLE_PRESS

halKeyWaitDuration = 0;

halKeyPressTimes = 0;

endif

}

}

当把每个按键的值放到寄存器s_u8KeyDebounce[i] |= u8Key;,当s_u8KeyDebounce[i] =0x00,或s_u8KeyDebounce[i]=0xff,时代表按键在80ms内的键值相同,可以确认按键状态已确认,给按键属性结构体填写相应的值,再调用回调函数(pHalKeyProcessFunction) (&keyAttribute),进行处理。keyAttribute.keys代表按键的序号,keyAttribute.behavior代表按键的行为,按键press down,press up,press release,press hold等等,keyAttribute.numattribute代表在一定时间段内连续按下的次数,keyAttribute.timeattribute代表按键hold住的时间。

通过ENABLE_MULTIPLE_PRESS来选择是否检测按键的多次按下通过ENABLE_HOLD_PRESS来选择是否检测按键长按的行为。其中KEYWAITDURATION定义了按键状态稳定后多次时间后处理按键多次按下的行为,KEYHOLDDURATION定义了按键按下至少多长时间才被认为是长按行为。

这三个数组初始化值定义最好是这样

static uint8 s_u8KeyDebounce[8] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};

static uint8 s_u8KeyState[8] = { 0,0,0,0,0,0,0,0 };

static uint8 s_u8_KeyStateInit[8] = {0,0,0,0,0,0,0,0};

这样才能保证上电时检测到按键初始状态并且调用回调函数进行处理。

下面的代码是处理按键多次按下以及hold的行为:

endif

endif

本文内容由小媛整理编辑!