优点:通用性高,精准,要求低
按键检测结构体
typedef struct
{
u8 (*IsKeyDownFunc)(void); /* 按键按下的判断函数,1表示按下 */
u8 Count; /* 滤波器计数器 */
u16 LongCount; /* 长按计数器 */
u16 LongTime; /* 按键按下持续时间, 0表示不检测长按 */
u8 FlagLongPressOccured; /* 长按标志,长按后打开,使扫描函数在按键放下后不发送短按信号*/
u8 State;
}key_t;
按键硬件初始化具体根据各家硬件决定,此处不谈。
按键软件初始化
u8 IsKeyDown(void) {if (!gpio_read(KEY_IO)) return 1;else return 0;}
key_t key;
void keyCheckInit(void)
{
key.LongTime = 200;
key.Count = 2;
key.State = 0;
key.IsKeyDownFunc = IsKeyDown;
}
说明,LongTime还决定了是否有长按检测
定时器中检测按键
if (key.IsKeyDownFunc())
{
//滤波
if (key.Count < 2)
{
key.Count++;
}
else
{
if (key.State == 0)
{
key.State = 1;
}
if (key.LongTime > 0)
{
if (key.LongCount < key.LongTime)
{
if (++key.LongCount == key.LongTime)
{
key.FlagLongPressOccured = 1;
//输出一个长按
}
}
}
}
}
else
{
if(key.Count != 0)
{
key.Count--;
}
else
{
if (key.State == 1)
{
key.State = 0;
if (key.FlagLongPressOccured == 1)
{
key.FlagLongPressOccured = 0;
}
}
}
key.LongCount = 0;
}
主循环中只需要判断key.FlagLongPressOccured是否为1即可判断是否有长按按下了。判断key.State即可判断是否有按键事件发生。