10 changed files with 217 additions and 18 deletions
@ -0,0 +1,44 @@ |
|||||
|
#include "task_btn.h" |
||||
|
#include "../bsp/bsp_btn.h" |
||||
|
#include "../bsp/bsp_config.h" |
||||
|
#include "../msp/UART0.h" |
||||
|
|
||||
|
void task_btn(void) |
||||
|
{ |
||||
|
switch(g_Key) |
||||
|
{ |
||||
|
case KEY_UP: |
||||
|
if(g_KeyActionFlag == LONG_KEY) |
||||
|
{ |
||||
|
L0_uart0_uc('#'); |
||||
|
L0_uart0_uchex(g_Key); |
||||
|
L0_uart0_0d0a(); |
||||
|
g_Key = KEY_NULL; |
||||
|
g_KeyActionFlag = NULL_KEY; |
||||
|
} |
||||
|
else if(g_KeyActionFlag == SHORT_KEY) |
||||
|
{ |
||||
|
L0_uart0_uc('@'); |
||||
|
L0_uart0_uchex(g_Key); |
||||
|
L0_uart0_0d0a(); |
||||
|
LED1 = ~LED1; |
||||
|
g_Key = KEY_NULL; |
||||
|
g_KeyActionFlag = NULL_KEY; |
||||
|
} |
||||
|
break; |
||||
|
case KEY_DOWN: |
||||
|
LED2 = ~LED2; |
||||
|
L0_uart0_uchex(g_Key); |
||||
|
L0_uart0_0d0a(); |
||||
|
g_Key = KEY_NULL; |
||||
|
break; |
||||
|
case KEY_PWR: |
||||
|
LED4 = ~LED4; |
||||
|
L0_uart0_uchex(g_Key); |
||||
|
L0_uart0_0d0a(); |
||||
|
g_Key = KEY_NULL; |
||||
|
break; |
||||
|
default: break; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,23 @@ |
|||||
|
/**
|
||||
|
* 使用定时器来轮询Key_Scan()函数,定时节拍为2ms, |
||||
|
* 状态转换时间为10ms,即每次进入switch case语句的时间差为10ms |
||||
|
* 利用该10ms的间隙跳过按键抖动 |
||||
|
*/ |
||||
|
#ifndef _app_task_btn_H |
||||
|
#define _app_task_btn_H |
||||
|
|
||||
|
// struct _s_task_key_
|
||||
|
// {
|
||||
|
// TS_task task;
|
||||
|
// vU8 key1_ok;
|
||||
|
// vU8 key2_ok;
|
||||
|
// vU8 key3_ok;
|
||||
|
// vU8 time1;
|
||||
|
// vU16 time2;
|
||||
|
// vU8 time3;
|
||||
|
// };
|
||||
|
// extern struct _s_task_key_ s_task_key_handle;
|
||||
|
// extern void L0_key_init(void);
|
||||
|
// extern void L3_task_key_handle(struct _s_task_key_ *p);
|
||||
|
extern void task_btn(void); |
||||
|
#endif |
@ -0,0 +1,84 @@ |
|||||
|
/*
|
||||
|
* 多个按键检测短按和长按事件 |
||||
|
* 短按:时间 10ms < T < 1 s, 长按:时间 T >1 s |
||||
|
* 功能:使用状态机方式,扫描单个按键;扫描周期为10ms,10ms刚好跳过抖动; |
||||
|
* 状态机使用switch case语句实现状态之间的跳转 |
||||
|
* lock变量用于判断是否是第一次进行按键确认状态 |
||||
|
* :按键释放后才执行按键事件 |
||||
|
*/ |
||||
|
|
||||
|
#include "bsp_btn.h" |
||||
|
#include "bsp_config.h" |
||||
|
#include "bsp_config.h" |
||||
|
#include "../msp/UART0.h" |
||||
|
|
||||
|
extern KEY_STATE KeyState = KEY_CHECK; // 初始化按键状态为检测状态
|
||||
|
KEY_TYPE g_KeyActionFlag = NULL_KEY; // 用于区别长按和短按
|
||||
|
KEY_VALUE g_Key = KEY_NULL; |
||||
|
u8 g_KeyFlag = 0; // 按键有效标志,0 无效 1 有效
|
||||
|
|
||||
|
static u8 TimeCnt = 0; //10ms为颗粒
|
||||
|
static u8 lock = 0; //lock变量用于判断是否是第一次进行按键确认状态
|
||||
|
|
||||
|
void Key_Scan(void) |
||||
|
{ |
||||
|
static u8 TimeCnt = 0; //10ms为颗粒
|
||||
|
static u8 lock = 0; |
||||
|
switch (KeyState) |
||||
|
{ |
||||
|
//按键未按下状态,此时判断Key的值
|
||||
|
case KEY_CHECK: |
||||
|
if(!Key) //如果按键Key值为0,说明按键开始按下,进入下一个状态
|
||||
|
{ |
||||
|
KeyState = KEY_COMFIRM; |
||||
|
} |
||||
|
TimeCnt = 0; //计数复位
|
||||
|
lock = 0; |
||||
|
break; |
||||
|
//按键按下状态确认:
|
||||
|
case KEY_COMFIRM: |
||||
|
if(!Key) //查看当前Key是否还是0,再次确认是否按下
|
||||
|
{ |
||||
|
if(!lock) lock = 1; //第一次进来置1
|
||||
|
TimeCnt ++; |
||||
|
// 多按键判断
|
||||
|
if(0 == key1) g_Key = KEY_UP; |
||||
|
else if(0 == key2) g_Key = KEY_DOWN; |
||||
|
else if(0 == key3) g_Key = KEY_PWR; |
||||
|
|
||||
|
if(TimeCnt > 200) // 长按 2 s
|
||||
|
{ |
||||
|
L0_uart0_uc('#'); |
||||
|
g_KeyActionFlag = LONG_KEY; |
||||
|
TimeCnt = 0; |
||||
|
lock = 0; //重新检查
|
||||
|
KeyState = KEY_RELEASE; // 需要进入按键释放状态
|
||||
|
} |
||||
|
// ???????????????????????
|
||||
|
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if(lock) //不是第一次进入,释放按键才执行
|
||||
|
{ |
||||
|
g_KeyActionFlag = SHORT_KEY; // 短按
|
||||
|
KeyState = KEY_RELEASE; // 需要进入按键释放状态
|
||||
|
} |
||||
|
else // 当前Key值为1,确认为抖动,则返回上一个状态
|
||||
|
{ |
||||
|
KeyState = KEY_CHECK; // 返回上一个状态
|
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
//按键释放状态
|
||||
|
case KEY_RELEASE: |
||||
|
if(Key) //当前Key值为1,说明按键已经释放,返回开始状态
|
||||
|
{ |
||||
|
KeyState = KEY_CHECK; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,39 @@ |
|||||
|
/**
|
||||
|
* 使用定时器来轮询Key_Scan()函数,定时节拍为2ms, |
||||
|
* 状态转换时间为10ms,即每次进入switch case语句的时间差为10ms |
||||
|
* 利用该10ms的间隙跳过按键抖动 |
||||
|
*/ |
||||
|
#ifndef _bsp_btn_H |
||||
|
#define _bsp_btn_H |
||||
|
|
||||
|
|
||||
|
// 区分长按和短按
|
||||
|
typedef enum |
||||
|
{ |
||||
|
NULL_KEY = 0, |
||||
|
SHORT_KEY = 1, |
||||
|
LONG_KEY = 2, |
||||
|
}KEY_TYPE; |
||||
|
|
||||
|
// 按键状态:检测、确认、释放
|
||||
|
typedef enum |
||||
|
{ |
||||
|
KEY_CHECK = 0, |
||||
|
KEY_COMFIRM = 1, |
||||
|
KEY_RELEASE = 2, |
||||
|
}KEY_STATE; |
||||
|
|
||||
|
// 按键值
|
||||
|
typedef enum |
||||
|
{ |
||||
|
KEY_NULL, |
||||
|
KEY_UP, |
||||
|
KEY_DOWN, |
||||
|
KEY_PWR, |
||||
|
}KEY_VALUE; |
||||
|
|
||||
|
extern KEY_VALUE g_Key; |
||||
|
extern KEY_TYPE g_KeyActionFlag; |
||||
|
|
||||
|
extern void Key_Scan(void); |
||||
|
|
Loading…
Reference in new issue