长按键C语言程序
一共用了四个按钮.
#define _KEYDOWN_TEST_TIME (20)
unsigned char IsKeyDown(volatile unsigned char Value, unsigned char pin)
{
unsigned long CurState = 0, i;
for(i = 0; i _KEYDOWN_TEST_TIME; ++i)
CurState += _GET_BIT(Value, pin)? 0:1; //键盘接了上拉电阻,低电平才是按下
if(CurState == _KEYDOWN_TEST_TIME)
return 1;
return 0;
}
//以下所有值均是以 DealWithKey函数的调用频率为基础的,该频率是定时器2的定时值决定的
//短按键的计数值,只有当按键检测计数器计数大于等于此值时才认为是一次短按
#define _KEY_SHORT_CNTR (2)
//长按键的计数值,只有当按键检测计数器计数大于等于此值时才认为是一次长按
#define _KEY_LONG_CNTR (_KEY_SHORT_CNTR * 3)
//无按键按下时的按键检测间隔,用于按键消抖动
#define _KEY_NORMAL_DEVIDER (2)
//此值用于按钮长按后,按钮检测函数的执行频率
#define _ADDMIN_FAST_DEVIDER (15)
//此值用于按钮短按后,按钮检测函数的执行频率
#define _ADDMIN_LONG_DEVIDER (_ADDMIN_FAST_DEVIDER * 3)
//此值用于设置蜂鸣器鸣响时间
#define _BEEPER_DEVIDER (10)
void DealWithKey(void)
{
static unsigned int AddCntr = 0;
static unsigned int MinCntr = 0;
static unsigned int UnitCntr = 0;
static unsigned int RunCntr = 0;
static unsigned char BeepCntr = 0;
static unsigned int DevCntr = 0;
static unsigned char LastRunState = 0;
unsigned char temp;
if(g_State != Setting) //运行状态, 所有按键都无效
return;
if(BeepCntr > 0) //处理蜂鸣器
--BeepCntr;
else
_BEEPER_OFF;
if(DevCntr) //按键处理分频器
{
--DevCntr;
return;
}
//这个按钮是可以重复进入的, 长按后先低频率动作, 当动作几次后再高频率动作
AddCntr = IsKeyDown(_PIN(_TO_KEY_ADD), _KEY_ADD)? AddCntr + 1 : 0;
if((temp = (AddCntr >= _KEY_LONG_CNTR)) || AddCntr >= _KEY_SHORT_CNTR)
{
...
}
//同上
MinCntr = IsKeyDown(_PIN(_TO_KEY_MIN), _KEY_MIN)? MinCntr + 1 : 0;
if((temp = (MinCntr >= _KEY_LONG_CNTR)) || MinCntr >= _KEY_SHORT_CNTR)
{
...
}
//这个按钮是不可重复进入的, 就是说只有抬起后再按下才动作
UnitCntr = IsKeyDown(_PIN(_TO_KEY_UNIT), _KEY_UNIT)? UnitCntr + 1 : 0;
if(UnitCntr == _KEY_SHORT_CNTR)
{
...
}
else if(UnitCntr > _KEY_SHORT_CNTR)
{
UnitCntr = _KEY_SHORT_CNTR + 1; //禁止重复执行
}
//这个按钮是要在按钮抬起后才执行其他函数的
if(IsKeyDown(_PIN(_TO_KEY_RUN), _KEY_RUN))
{
++RunCntr;
}
else
{
RunCntr = 0;
if(LastRunState) //表明键已经按下后才抬起的
{
LastRunState = 0;
g_State = EmptyInflatting;
}
}
if(RunCntr == _KEY_SHORT_CNTR)
{
BeepCntr = _BEEPER_DEVIDER;
_BEEPER_ON;
LastRunState = 1; //此键是抬起时生效.
}
else if(RunCntr > _KEY_SHORT_CNTR)
{
RunCntr = _KEY_SHORT_CNTR + 1; //禁止重复执行
}
DevCntr = _KEY_NORMAL_DEVIDER;
}
评论