<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2009年10月7日星期三15:32:23<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
标题:按键的工作方式02
最近又翻阅了一些书,更深入的了解了各种按键的工作方式,下面把我编程过程中的一些体会说一下。
一、短击与连击的实现
1、特点:该按键可同时实现短击、超过一定时间不释放,则按键自动重复。
2、实现背景:在UCOS操作系统下,单独的一个键,利用状态机。
3、程序的简单分析:
void Task_FiveOK(void *pdata)
{
u8 FiveOKState; //FiveOK是我给这个键起的名字
KeyStateMachine KeySM="WaitForPress"; //键盘状态机是一个枚举变量,
// 初始状态为等待按下
pdata=pdata;
for(;;)
{
OSTimeDly(1); //时钟频率为100Hz,每隔10ms扫描一次键盘。
FiveOKState=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15); //最简单的单线按键,直接读取电平
switch(KeySM) //根据状态机的当前状态
{
case WaitForPress: //等待按键
if(FiveOKState==0) //低电平为有键按下
{KeySM=KeyVerify1; //设置状态为按键确认1,10ms后进行按键确认。
}
break;
case KeyVerify1: //第一次确认,如果仍然是低电平,则进入确认2状态
if(FiveOKState==0)
{KeySM=KeyVerify2;
}
else
{KeySM=WaitForPress; //否则回到等待按键状态
}
break;
case KeyVerify2: //确认2状态下,如果仍为低电平,则真的按下了,
if(FiveOKState==0)
{KeySM=WaitForRelease; //转入等待释放阶段
Key[KeyNum]=KeyOK;
OSQPost(KeyOSQ,&Key[KeyNum]); //向消息队列发送按键值
KeyNum++;
}
else
{KeySM=WaitForPress;
}
break;
case WaitForRelease: //按键会保持一段时间,并进行按下时间计数
if(FiveOKState==0)
{KeySM=WaitForRelease;
PressTimeCount++; //按下时间计数
if(!LongPress) //连击标志未设置时
{
if(PressTimeCount==100) 计时超过1s,设置连击标志
{LongPress=1;
PressTimeCount=0;
}
}
Else //连击标志已设置
{
if(PressTimeCount==10) 每隔0.1s发送一次按键消息
{Key[KeyNum]=KeyOK;
OSQPost(KeyOSQ,&Key[KeyNum]);
KeyNum++;
PressTimeCount=0;
}
}
}
else
{
KeySM=KeyReleasing;
}
break;
case KeyReleasing: //在等待释放阶段,检测到高电平转入此阶段
if(FiveOKState==0) //如果检测到低电平,说明刚刚的高电平为干扰,回到等待释放阶段。
{KeySM=WaitForRelease;
PressTimeCount++;
}
Else //如果仍然是高电平,则的确是释放了,回到等到按键状态。
{KeySM=WaitForPress;
LongPress=0;
PressTimeCount=0;
}
break;
default:
break;
}
}
}
文章评论(0条评论)
登录后参与讨论