伍:按键驱动(短按、长按、双击)
2016-07-06 本文已影响304人
恰冯同学年少
按键扫描驱动,支持按键的长按和短按事件(未实现双击事件),key_Scan()函数得到相应的键值,主程序根据键值进行动作。
三个按键:Key_SPA Key_ZER Key_MEN
Key_Board.h
#ifndef Key_Board
#define Key_Board
#include <SH79F1611.h>
#include "Timer_Init.h"
typedef struct
{
unsigned char Short_Press:1; //短按
unsigned char Long_Press:1; //长按
unsigned char Double_Press:1; //双击
}Key_State;
extern xdata Key_State Key_SPA,Key_ZER,Key_MEN;
void Key_Init(void);
void Key_Scan(void);
#endif
key_Board.c
#include "Key_Board.h"
sbit SPA = P4^3;
sbit ZER = P4^2;
////按键状态结构体定义 三个按键 SPA/ZER/MEN
xdata Key_State Key_SPA = {0,0,0};
xdata Key_State Key_ZER = {0,0,0};
xdata Key_State Key_MEN = {0,0,0};
//按键初始化
void Key_Init(void)
{
P4CR &= ~0x0c; //P4^2 P4^3 设置为输入接口
P4PCR |= 0x0c; //输入上拉
P4CR |= 0x02; //P4.1输出 作为按键地
P4 &= ~0x02;
}
bit Key_Down_SPA_Short = 1;
bit Key_Down_ZER_Short = 1;
bit Key_Down_MEN_Short = 1;
bit Key_Down_SPA_Long = 1;
bit Key_Down_ZER_Long = 1;
bit Key_Down_MEN_Long = 1;
/*****************************************************************************
*1:按键扫描函数 三个按键公用两个IO口 先扫描SPA/ZER按键 再扫描MOD按键
*2:程序支持按键短按和长按 短按按键在按键抬起后取值 长按按键在按键按下时可取值
*3:按键长按后抬起,取得长按键值,短按键值被屏蔽
******************************************************************************/
void Key_Scan(void)
{
static xdata char cnt = 0;
if((SPA==0) && (ZER==0)) //不支持同时按键
{
return ;
}
if(SPA == 0) //当SPA按键按下
{
if((Key_Down_SPA_Short == 1)&&(Key_Down_SPA_Long == 1))
{
if(cnt++ >= 1) //20ms防抖
{
cnt = 0;
Key_Down_SPA_Short = 0;
Key_Timing = 0; //按键计数变量清0
}
}
else
if(Key_Down_SPA_Long == 1)
{
if(Key_Timing >= 300)
{
Key_Timing = 0;
Key_Down_SPA_Long = 0;
Key_SPA.Long_Press = 1;
Key_Down_SPA_Short = 1;
}
}
}
else
if(ZER == 0) //当ZER按键按下
{
if((Key_Down_ZER_Short == 1)&&(Key_Down_ZER_Long == 1))
{
if(cnt++ >= 1) //20ms防抖
{
cnt = 0;
Key_Down_ZER_Short = 0;
Key_Timing = 0; //按键计数变量清0
}
}
else
if(Key_Down_ZER_Long == 1)
{
if(Key_Timing >= 200)
{
Key_Timing = 0;
Key_Down_ZER_Long = 0;
Key_ZER.Long_Press = 1;
Key_Down_ZER_Short = 1;
}
}
}
else
{
P4CR |= 0x04; //设置ZER按键对应的IO口为输出 输出为0
ZER = 0;
if(SPA == 0) //当MOD按键按下
{
if((Key_Down_MEN_Short == 1)&&(Key_Down_MEN_Long == 1))
{
if(cnt++ >= 1) //20ms防抖
{
cnt = 0;
Key_Down_MEN_Short = 0;
Key_Timing = 0; //按键计数变量清0
}
}
else
if(Key_Down_MEN_Long == 1)
{
if(Key_Timing >= 200)
{
Key_Timing = 0;
Key_Down_MEN_Long = 0;
Key_MEN.Long_Press = 1;
Key_Down_MEN_Short = 1;
}
}
}
else
if((SPA == 1) && ((Key_Down_MEN_Short == 0) || (Key_Down_MEN_Long == 0)))
{
if(Key_Down_MEN_Short == 0)
{
Key_Down_MEN_Short = 1;
Key_MEN.Short_Press = 1; //MEN短按
}
if(Key_Down_MEN_Long == 0)
{
Key_Down_MEN_Long = 1;
Key_MEN.Long_Press = 0;
}
}
P4CR &= ~0x04; //设置ZER按键对应的IO口为输入
P4PCR |= 0x04; //输入上拉
}
if(SPA == 1)
{
if(Key_Down_SPA_Short == 0)
{
Key_Down_SPA_Short = 1;
Key_SPA.Short_Press = 1;
}
if(Key_Down_SPA_Long == 0)
{
Key_Down_SPA_Long = 1;
Key_SPA.Long_Press = 0;
}
}
if(ZER == 1)
{
if(Key_Down_ZER_Short == 0)
{
Key_Down_ZER_Short = 1;
Key_ZER.Short_Press = 1;
}
if(Key_Down_ZER_Long == 0)
{
Key_Down_ZER_Long = 1;
Key_ZER.Long_Press = 0;
}
}
if(Key_ZER.Long_Press==1 || Key_ZER.Short_Press==1 || Key_SPA.Long_Press==1 || Key_SPA.Short_Press==1 || Key_MEN.Long_Press==1 ||Key_MEN.Short_Press==1)
{
Set_Menu_Timeouy_5s = 0; //有按键按下 菜单计数清0
}
}