搜索
bottom↓
回复: 9

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

[复制链接]

出0入0汤圆

发表于 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;
}

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-3-16 20:56:04 | 显示全部楼层
请教,原理上应该是松开手才作用对吧?

出0入0汤圆

 楼主| 发表于 2013-3-16 22:02:33 | 显示全部楼层
如果按住某键的话,应该不会跳出这个程序的吧

出0入0汤圆

发表于 2013-3-16 23:41:57 | 显示全部楼层
这要看实际要求。PC机按住就算是一个按键动作。按下是一个动作,释放是一个动作,按下+释放也可以是一个动作。这要看具体要求。不同的具体应用,有不同的设计方法。

出0入0汤圆

 楼主| 发表于 2013-3-16 23:48:18 | 显示全部楼层
wsygb 发表于 2013-3-16 23:41
这要看实际要求。PC机按住就算是一个按键动作。按下是一个动作,释放是一个动作,按下+释放也可以是一个动 ...

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

出0入0汤圆

发表于 2013-3-17 00:07:13 | 显示全部楼层
从函数的角度说,每调用一次这个函数都有返回值,但返回值与键值不是同一个概念。读程序注释,键释放后才有键值(应该是非零值吧)返回。一般来说,我不会采用这样的设计方法。而是,返回一个确定的按键状态值,无论是按下还是释放。

出0入0汤圆

 楼主| 发表于 2013-3-17 00:17:46 | 显示全部楼层
wsygb 发表于 2013-3-17 00:07
从函数的角度说,每调用一次这个函数都有返回值,但返回值与键值不是同一个概念。读程序注释,键释放后才有 ...

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

出0入0汤圆

发表于 2013-3-17 12:48:36 | 显示全部楼层
你把最后一句:"return key_return;” 放到"case 2:"中去试试看什么效果。

出0入0汤圆

发表于 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进入相关的状态的。

出0入0汤圆

 楼主| 发表于 2013-3-17 19:50:32 | 显示全部楼层
wsygb 发表于 2013-3-17 13:33
(1)这个函数的返回值的只有这个出口 return key_ret 。你想将return key_ret放再CASE 2的那个位置?
(2) ...

嗯,我想通是怎么回事了,谢谢你耐心的回答!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表