星星亮了夜空 发表于 2013-3-16 20:32:26

请教:基于状态机分析的按键问题

应用马老师书上基于状态机的按键方法时,键一按下不等松开就作用,为什么不是松开后才起作用?
unsigned char Getkey()
{
static unsigned char key_state = 0,key_value,key_line;
unsigned char key_return = NO_key, i;
switch(key_state)
{
case 0:
key_line = 0b00010000;
for (i = 1; i <= 4; i++)                        //扫描键盘
{
    PORTX = ~key_line;                              //输出行线电平
    PORTX = ~key_line;                              //送2次
    key_value = Key_mask & PINX;      //读列电平
    if(key_value == Key_mask)
    key_line <<= 1;                              //没有按键继续扫描
    else
    {
   key_state++;                              //有按键,停止扫描
   break;                                                //转消抖确认状态
    }
   }
    break;
               
case 1:
if(key_value == (Key_mask & PINX))      //再次读列电平
{
   switch (key_line | key_value)      //与状态0的相同,确认按键
   {                                    //键盘编码,返回编码值
    case 0b00011110:
   key_return = K1;                                       
   break;
……
    case 0b10000111:
   key_return = K16;
   break;
   }
   key_state++;                                        //转入等待按键释放状态
}
else
{
   key_state--;                                        //两次列电平不同,返回状态0(消抖处理)
}
break;
               
case 2:                                                                        //等待按键释放状态
PORTX = 0b00001111;                                        //行线全部输出低电平
PORTX = 0b00001111;                                        //重复送一次
if((Key_mask & PINX) == Key_mask)
{
   key_state = 0;                                        //列线全部为高电平,返回状态0
}
break;
}
return key_return;
}

应用马老师书上基于状态机的按键方法时,键一按下不等松开就作用,为什么不是松开后才起作用?

星星亮了夜空 发表于 2013-3-16 20:56:04

请教,原理上应该是松开手才作用对吧?

星星亮了夜空 发表于 2013-3-16 22:02:33

如果按住某键的话,应该不会跳出这个程序的吧

wsygb 发表于 2013-3-16 23:41:57

这要看实际要求。PC机按住就算是一个按键动作。按下是一个动作,释放是一个动作,按下+释放也可以是一个动作。这要看具体要求。不同的具体应用,有不同的设计方法。

星星亮了夜空 发表于 2013-3-16 23:48:18

wsygb 发表于 2013-3-16 23:41 static/image/common/back.gif
这要看实际要求。PC机按住就算是一个按键动作。按下是一个动作,释放是一个动作,按下+释放也可以是一个动 ...

就上面这个程序来讲,主程序调用它时,是不是松开按键的时候才会读到返回值呢?

wsygb 发表于 2013-3-17 00:07:13

从函数的角度说,每调用一次这个函数都有返回值,但返回值与键值不是同一个概念。读程序注释,键释放后才有键值(应该是非零值吧)返回。一般来说,我不会采用这样的设计方法。而是,返回一个确定的按键状态值,无论是按下还是释放。

星星亮了夜空 发表于 2013-3-17 00:17:46

wsygb 发表于 2013-3-17 00:07 static/image/common/back.gif
从函数的角度说,每调用一次这个函数都有返回值,但返回值与键值不是同一个概念。读程序注释,键释放后才有 ...

嗯,不好意思,我没把前面的宏定义加上,#define k1 1……,我想请问为什么实际执行中按键没松就已经执行了?应该是程序的原因吧……

wxty 发表于 2013-3-17 12:48:36

你把最后一句:"return key_return;” 放到"case 2:"中去试试看什么效果。

wsygb 发表于 2013-3-17 13:33:14

本帖最后由 wsygb 于 2013-3-17 13:41 编辑

(1)这个函数的返回值的只有这个出口 return key_ret 。你想将return key_ret放再CASE 2的那个位置?
(2)”实际执行中按键没松就已经执行“是什么意思。执行了什么?它返回的值是什么?
(3)这个程序是不延时等待按键的释放,或按下。而是上层程序定时调用这个函数。注意这是静态变量的定义static unsigned char key_state = 0,每次进入这个函数,是根据key_state进入相关的状态的。

星星亮了夜空 发表于 2013-3-17 19:50:32

wsygb 发表于 2013-3-17 13:33 static/image/common/back.gif
(1)这个函数的返回值的只有这个出口 return key_ret 。你想将return key_ret放再CASE 2的那个位置?
(2) ...

嗯,我想通是怎么回事了,谢谢你耐心的回答!
页: [1]
查看完整版本: 请教:基于状态机分析的按键问题