前言:大家知道,我们在单片机的键盘处理程序中,经常使用延时操作.目的当然是为了去除抖动.延时去抖的效果是可靠而且简单的.但是,对于经常的键盘操作,延时操作就会降低系统的实时性.而且,关键的是,延时算法对于处理组合键就显得不那么得心应手了.
今天我们一起交流的就是这个"基于事件处理"的键盘处理程序.
"基于事件"这个想法是从VB程序中得到的.简单的说,VB程序的工作机制是:程序检测用户操作,检测到用户行为后,发出相应的消息给系统.但是到底对不对这个消息进行处理,则是由另外的消息处理程序进行.移植到我们这个单片机上,就是:单片机检测到了用户的行为,置相关的标志位(发出消息),但是到底对不对这个标志位进行理睬,则是由相应的处理函数决定的.
下面我们就看一看c语言的例子:
//申请一个存储按键状态的结构体
struct Keyboard
{
unsigned char S1_DOWN; //标志位,标志S1按键被按下
unsigned int S1_Count; //S1按键用来去抖的计数器
unsigned char S2_DOWN; //标志位,标志S2按键被按下
unsigned int S2_Count; //S2按键用来去抖的计数器
unsigned char Others_Down; //用来标志是否有除自身以外的其他按键按下
};
在下面的主程序中,我们示意一下这种按键处理怎么做,以及它的优缺点:
#define S1 P0^0 //定义S1为P0^0
#define S2 p0^1 //定义S1为P0^1
void main()
{
for(;;)
{
//****************** 消息产生 **************************************
if(S1= =0) //如果有S1按下
{
Keyboard.S1_Count++; //开始去抖计数
if(Keyboard.S1_Count>150) //这个值是自己系统的情况需要改变.
{
Keyboard.S1_DOWN=YES; //产生消息
}
if(S2_DOWN= = 0) //如果S2也按下
{
Keyboard.Others_DOWN=YES;
}
}
else
{
Keyboard.S1_DOWN=NO;
Keyboard.S1_Count=0;
Keyboard.Others_DOWN=NO;
}
} //The End Of If
//********************* 消息处理 **************************************
if(Keyboard.S1_DOWN= =YES&&Keyboard.Others_DOWN= =NO) //Only S1 down
{
//your code here
}
else if(Keyboard.S1_DOWN= =YES&&Keyboard.Others_DOWN= =YES) //组合键
{
if(Keyboard.S2_DOWN= =YES) //这是S1和S2都按下的情况.
{
//your code here
}
}
}
从上面来看,主程序是在一直循环的,可以方便的处理组合键的情况.在多个项目中使用都没有发现问题.
程序有写复杂,但是条理清晰.
Cybershu 2009-3-14 15:54