搜索
bottom↓
回复: 3

<从单片机初学者迈向单片机工程师> 中按键部分实际应用...

[复制链接]

出0入0汤圆

发表于 2012-6-6 01:48:52 | 显示全部楼层 |阅读模式
本帖最后由 desgh 于 2012-6-6 17:42 编辑

void GetKey(uint8 *pKeyValue)
{
static uint8 s_u8KeyState = KEY_STATE_INIT ;
static uint8 s_u8KeyTimeCount = 0 ;
static uint8 s_u8LastKey = KEY_NULL ; //保存按键释放时候的键值
uint8 KeyTemp = KEY_NULL ;
KeyTemp = KeyScan() ; //获取键值
switch(s_u8KeyState)
{
case KEY_STATE_INIT :
{
if(KEY_NULL != (KeyTemp))
{
s_u8KeyState = KEY_STATE_WOBBLE ;
}
}
break ;
case KEY_STATE_WOBBLE : //消抖
{
s_u8KeyState = KEY_STATE_PRESS ;
}
break ;
case KEY_STATE_PRESS :
{
if(KEY_NULL != (KeyTemp))
{
s_u8LastKey = KeyTemp ; //保存键值,以便在释放按键状态返回
键值
KeyTemp |= KEY_DOWN ; //按键按下
s_u8KeyState = KEY_STATE_LONG ;
}
else
{
s_u8KeyState = KEY_STATE_INIT ;
}
}
break ;
case KEY_STATE_LONG :
{
if(KEY_NULL != (KeyTemp))
{
if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
{
s_u8KeyTimeCount = 0 ;
KeyTemp |= KEY_LONG ; //长按键事件发生
s_u8KeyState = KEY_STATE_CONTINUE ;
}
}
else
{
s_u8KeyState = KEY_STATE_RELEASE ;
}
}
break ;
case KEY_STATE_CONTINUE :
{
if(KEY_NULL != (KeyTemp))
{
if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD)
{
s_u8KeyTimeCount = 0 ;
KeyTemp |= KEY_CONTINUE ;
}
}
else
{
s_u8KeyState = KEY_STATE_RELEASE ;
}
}
break ;
case KEY_STATE_RELEASE :
{
s_u8LastKey |= KEY_UP ;
KeyTemp = s_u8LastKey ;
s_u8KeyState = KEY_STATE_INIT ;
}
break ;
default : break ;
}
*pKeyValue = KeyTemp ; //返回键值+按键状态

}

上面是原文,修改了下,大家多多指点:

void GetKey(uint8 *pKeyValue)   //获取键值
{
    static uint8 s_u8KeyState = KEY_STATE_INIT ;  //  
    static uint8 s_u8KeyTimeCount = 0 ;                          //
    static uint8 s_u8LastKey = KEY_NULL ;   
    uint8 KeyTemp = KEY_NULL ;                                //  

    KeyTemp = KeyScan() ;       //获取键值
    switch(s_u8KeyState)
    {
         case KEY_STATE_INIT:
         {
              if(KEY_NULL != (KeyTemp) )
              {
                  s_u8KeyState = KEY_STATE_WOBBLE ;
              }
         }
         break ;
         
         case KEY_STATE_WOBBLE :
         {
                  s_u8KeyState = KEY_STATE_PRESS ;
         }
         break ;

         case KEY_STATE_PRESS :                                  //消抖
         {
              if(KEY_NULL != (KeyTemp) )
              {
                s_u8LastKey = KeyTemp ; //保存键值
               
                s_u8LastKey |= KEY_DOWN ;
                s_u8KeyState = KEY_STATE_LONG ;

              }
              else
              {
                s_u8KeyState = KEY_STATE_INIT ;
              }
         }
         break ;
      
         case KEY_STATE_LONG:
         {
             if(KEY_NULL != (KeyTemp) )
             {
                 if(++s_u8KeyTimeCount > KEY_LONG_PERIOD )
                 {
                    s_u8KeyTimeCount = 0 ;
                    s_u8LastKey &= 0x0f;
                    s_u8LastKey |= KEY_LONG ;
                    s_u8KeyState = KEY_STATE_CONTINUE ;
                 }
             }
             else
             {
               s_u8KeyState = KEY_STATE_RELEASE ;
             }
         }
         break ;
   
         case KEY_STATE_CONTINUE :
         {
             if(KEY_NULL != (KeyTemp) )
             {
                 if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD )
                 {
                    s_u8KeyTimeCount = 0 ;
            s_u8LastKey &= 0x0f;
                    s_u8LastKey |= KEY_CONTINUE ;
                 }
             }
             else
             {
               s_u8KeyState = KEY_STATE_RELEASE ;
             }
         }
         break ;

         case KEY_STATE_RELEASE :
         {
              
             KeyTemp = s_u8LastKey ;
             s_u8LastKey |= KEY_UP ;
             s_u8KeyState = KEY_STATE_INIT ;
         }
         break ;

         default : break;

    }
    *pKeyValue = KeyTemp ; //返回键值

}

还望各位多交流交流!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-6-6 02:30:12 | 显示全部楼层
我觉得楼主没领会作者的意图啊,s_u8last key只有一个作用,就是在release态时产生返回形式为(keyTemp | KEY_UP )的键值表达式,然后主程序中采用(KEY_UP )检测抬手动作,应该是没问题的。而反观楼主程序,显然画蛇添足了,而且第一次抬手检测也有问题吧?楼主是在实测中发现原程序不行的?确定按照正确的方法调用这个按键程序?

出0入0汤圆

 楼主| 发表于 2012-6-6 12:39:13 | 显示全部楼层
锦瑟华年 发表于 2012-6-6 02:30
我觉得楼主没领会作者的意图啊,s_u8last key只有一个作用,就是在release态时产生返回形式为(keyTemp | K ...

多谢指导!
学艺不精,惭愧了!
这样写就是简化在主程序 中还要去判断 KEY_UP,所以做了点小改动!嘻嘻!  等到按键释放了才返回值,当然了如果你是不需要这样做 ,比方说长按后数据会连续增加,或者连发数据会连续增加就不用等到按键释放了!

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 02:26

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

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