不用delay函数的按键扫描函数
//============================================================
typedef enum{
OFF,
ON,
BLINK,
}LED_TypeDef;
typedef enum{
NO_KEY,
KEY1_PRESS, /* 按下 */
KEY1_SHORT_RELEASE, /* 按下立马释放 */
KEY1_LONG_PRESS, /* 长按 */
KEY1_LONG_RELEASE, /* 长按后释放 */
KEY2_PRESS, /* 按下 */
KEY2_SHORT_RELEASE, /* 按下立马释放 */
KEY2_LONG_PRESS, /* 长按 */
KEY2_LONG_RELEASE, /* 长按后释放 */
}KEY_TypeDef;
//============================================================
void led_task(void)//200ms定时器
{
//DBG("%s\n", __FUNCTION__);//log
static unsigned char i = 0;
switch (LedFlag) {
case OFF:
LED1OFF();
break;
case ON:
LED1ON();
break;
case BLINK:
if(i++ % 2) LED1ON();
else LED1OFF();
break;
default:
break;
}
}
#define KEY_TIME_OUT 50//消抖时间,取决于while(1)的速度
KEY_TypeDef key_scan(void)
{
static KEY_TypeDef status = NO_KEY;
static unsigned int index = 0;
if(gpio_read(KEY1) == 0 || gpio_read(KEY2) == 0)
{
index++;
//DBG("index = %d\n", index);
if(index == KEY_TIME_OUT)//根据scanf_key执行频率设置具体数值
{
if(gpio_read(KEY1) == 0){
status = KEY1_PRESS;
return status;
}else if(gpio_read(KEY2) == 0){
status = KEY2_PRESS;
return status;
}
}
if(index == KEY_TIME_OUT * 150)// 150 大概等于 3s 根据scanf_key执行频率设置具体数值
{
if(gpio_read(KEY1) == 0){
status = KEY1_LONG_PRESS;
return status;
}else if(gpio_read(KEY2) == 0){
status = KEY2_LONG_PRESS;
return status;
}
}
}
else
{
switch (status) {
case KEY1_PRESS: status = KEY1_SHORT_RELEASE; return status; break;
case KEY2_PRESS: status = KEY2_SHORT_RELEASE; return status; break;
case KEY1_LONG_PRESS: status = KEY1_LONG_RELEASE; return status; break;
case KEY2_LONG_PRESS: status = KEY2_LONG_RELEASE; return status; break;
default: break;
}
index = 0;
status = NO_KEY;
}
return NO_KEY;
}
//放while(1)循环处理
void key_task(void)
{
static unsigned char key_index = 0;// up stop down stop
KEY_TypeDef key = key_scan();
if(key) DBG("key = %d, key_index = %d\n", key, key_index);
switch (key) {
case KEY1_SHORT_RELEASE://学习配对按键
learning_key();
break;
case KEY2_SHORT_RELEASE://电机控制按键
motor_set(key_index++);
key_index = key_index%4;//控制key_index范围 0-3
break;
case KEY1_LONG_PRESS: //清楚配对按键
user_rest();
break;
case KEY2_LONG_PRESS: //遥控器上下转向
Remote_inversion = !Remote_inversion;
user_flash_Remote_write(Remote_inversion);//保存到flash
LedFlag = OFF;
software_timer_init(&LedOffTimeHandle, led_auto_off, LED_OFF_TIME>>1, 0);//LED复位5秒
software_timer_start(&LedOffTimeHandle);
DBG("Remote_inversion = %d\n", Remote_inversion);
break;
default:
break;
}
}
按键未按下返回 0
按键按下消抖后返回 1
按键一直按下返回 2