搜索
bottom↓
12
返回列表 发新帖
楼主: nicksean

通用按键消抖函数 -- 数据与过程分离【恢复】

[复制链接]

出0入296汤圆

发表于 2010-9-19 09:53:02 | 显示全部楼层

出0入296汤圆

发表于 2010-9-19 09:56:31 | 显示全部楼层

出0入296汤圆

发表于 2010-9-19 09:59:28 | 显示全部楼层
//键盘处理模块
# define KEY_NULL       0xFF
# define _USE_KEY_LONG_PRESS_REPEAT
# define _USE_KEY_LONG_PRESS_DELAY_TIME         1024
# define _USE_KEY_LONG_KEY_FASTEST_SPEED_LEVEL  3
# define _USE_KEY_PRESS_SCAN_FUNC_INTERFACE Key_Press_Scan


这是一个使用的代码范例片断

    if (Get_Key_Code())
    {
        //检测普通按键
        s_cIdleTimeCounter = 0;
        CLS
        switch (g_cReturnKeyNum)                           
        {
            case KEY_UP:
                if (s_pDISPMenuItem == s_pCurrentMenuItem)
                {
                    if (s_pCurrentMenuItem->pPreviouse != NULL)
                    {
                        s_pCurrentMenuItem = s_pCurrentMenuItem->pPreviouse;
                        s_pDISPMenuItem = s_pCurrentMenuItem;
                    }
                }
                else
                {
                    s_pCurrentMenuItem = s_pDISPMenuItem;
                }
                break;
            case KEY_DOWN:
                if (s_pDISPMenuItem == s_pCurrentMenuItem)
                {
                    if (s_pCurrentMenuItem->pNext != NULL)
                    {
                        s_pCurrentMenuItem = s_pCurrentMenuItem->pNext;
                    }
                }
                else
                {
                    s_pDISPMenuItem = s_pCurrentMenuItem;
                    if (s_pCurrentMenuItem->pNext != NULL)
                    {
                        s_pCurrentMenuItem = s_pCurrentMenuItem->pNext;
                    }
                }
                break;
            case KEY_RIGHT:
            case KEY_5:
            case KEY_ENTER:
                if (s_pCurrentMenuItem->pChild != NULL)
                {
                    s_pCurrentMenuItem = s_pCurrentMenuItem->pChild;
                    s_pDISPMenuItem = s_pCurrentMenuItem;
                }
                else if (s_pCurrentMenuItem->fnTask != NULL)
                {
                    (s_pCurrentMenuItem->fnTask)();         //调用函数
                }
                else
                {
                    CLS;
                    LOCATE(1,2);
                    PRINT("PRESS ANY KEY...");
                    while(!Get_Key_Code())
                    {
                        Flash("ERROR: NULL ITEM!",' ',1,1);
                    }
                    CLS
                }
                break;
            case KEY_LEFT:
                if (s_pCurrentMenuItem->pParent != NULL)
                {
                    s_pCurrentMenuItem = s_pCurrentMenuItem->pParent;
                    s_pDISPMenuItem = s_pCurrentMenuItem;
                }
                break;
            default:
                break;
        }
        
        //检测长按键
        switch (g_cReturnLongPressKeyNum)
        {
            case KEY_LEFT:                                  //长按LEFT键返回根目录
                s_pCurrentMenuItem = s_pMenuRoot;
                s_pDISPMenuItem = s_pCurrentMenuItem;
                break;
            default:
                break;
        }
    }


<font color=blur>相关帖子及完整下载(包含一个完整的菜单处理系统)
点击此处下载ourdev_175041.rar(文件大小:312K)

出0入0汤圆

发表于 2010-9-19 21:26:34 | 显示全部楼层
遇到高人了,拜一拜!收藏

出0入0汤圆

发表于 2010-9-19 21:53:53 | 显示全部楼层
不错,顶了!

出0入0汤圆

发表于 2010-9-20 14:26:46 | 显示全部楼层
脚印

出0入0汤圆

发表于 2010-9-20 15:26:51 | 显示全部楼层
我也来一个数据与过程分离的按键函数吧

#include "Global.h"

_CONST_ROM_ KEY_PARAM c_aKeyParam_Tab[] =
{//按键消息,按键长短按功能都在这里填上去就可以了
{KEY_NUM0,    LONG_PRESS_NONE},
{KEY_NUM1,    LONG_PRESS_NONE},
{KEY_NUM2,    LONG_PRESS_NONE},
{KEY_NUM3,    LONG_PRESS_NONE},  
{KEY_NUM4,    LONG_PRESS_NONE},
{KEY_NUM5,    LONG_PRESS_NONE},
{KEY_NUM6,    LONG_PRESS_NONE},
{KEY_NUM7,    LONG_PRESS_NONE},  
{KEY_NUM8,    LONG_PRESS_NONE},
{KEY_NUM9,    LONG_PRESS_NONE},
{KEY_POWER,   LONG_PRESS_NONE},
{KEY_VOLUP,   LONG_PRESS_HOLD_SHORT},
{KEY_VOLDN,   LONG_PRESS_HOLD_SHORT},
{KEY_UP,      LONG_PRESS_NONE},
{KEY_DOWN,    LONG_PRESS_NONE},
{KEY_LEFT,    LONG_PRESS_NONE},  
{KEY_RIGHT,   LONG_PRESS_NONE},
{KEY_ENTER,   LONG_PRESS_NONE},
{KEY_EXIT,    LONG_PRESS_NONE},  
};

UINT8 Get_Max_Key(void)
{
return (sizeof(c_aKeyParam_Tab)/sizeof(KEY_PARAM));
}

void Key_Init(void)//该函数初始化调用即可
{
Clr_Key();

#ifdef SUPPORT_ADC
ADC_Init();
#endif

}

void Key_Proc(void)//此函数放在主循环处一直调用
{
UINT16 m_uiKeyCodeHead;

  ADC_Read_Proc();//ad值获取(如果用矩阵或独立按键就不需要此函数)
  Key_Scan(Get_AdKeyCode());//按键扫描(Get_AdKeyCode()是ad处理得出来的按键消息)
  //Key_Scan是处理按键的过程,Get_AdKeyCode是处理按键的数据
m_uiKeyCodeHead = Get_Msg_Type();
if((m_uiKeyCodeHead != MSG_KEY)&&(m_uiKeyCodeHead != MSG_IR))
{
  Clr_Key();
  return;//没有按键或遥控消息退出
}

Comm_Key_Proc();//按键功能处理用这个函数

Clr_Key();
}

#ifndef __KEY_H__
#define __KEY_H__


enum {//按键消息枚举
KEY_ERR = 0,
KEY_POWER,
KEY_VOLUP,
KEY_VOLDN,
KEY_NUM0,
KEY_NUM1,
KEY_NUM2,
KEY_NUM3,
KEY_NUM4,
KEY_NUM5,
KEY_NUM6,
KEY_NUM7,
KEY_NUM8,
KEY_NUM9,
KEY_UP,
KEY_DOWN,
KEY_LEFT,
KEY_RIGHT,
KEY_ENTER,
KEY_EXIT,

/* Max Key 0xfe */
KEY_NULL = 0xff,
};


extern _CONST_ROM_ KEY_PARAM c_aKeyParam_Tab[];

extern UINT8 Get_Max_Key(void);
extern void Key_Init(void);
extern void Key_Proc(void);

#endif

#include "Global.h"

KEY_INFO g_KeyInfo = {KEY_NULL,0,0,0,0,LONG_PRESS_NONE};//按键扫描结构体
UINT16 g_uiKeyCode;//这个是全局按键消息变量

void Key_Scan(UINT8 m_ucKeyCode)//按键扫描,这个也是数据与过程分离的
{
  UINT8 m_ucKeyIndex;               
       
   
  if(m_ucKeyCode == KEY_NULL)
  {
    if(KEY_NULL == g_KeyInfo.Val) //没有按键按下
    {
      return;
    }
    if((g_KeyInfo.Interval >= TICK_STILL_PRESSED_STEP)
    //&&(g_KeyInfo.Duration < TICK_TH_SHORT_PRESS))
    &&(g_KeyInfo.Duration < TICK_TH_LONG_PRESS))//按键已经释放
    {
     if((g_KeyInfo.Status != (PRESS_KEY_DOWN|KEY_TIME_LONG)>>8)
      &&((g_KeyInfo.KeyHoldPeriod == LONG_PRESS_ONCE)
       ||(g_KeyInfo.KeyHoldPeriod == LONG_PRESS_HOLD_LONG)
       ||(g_KeyInfo.KeyHoldPeriod == LONG_PRESS_HOLD_SHORT))
     )
     {
      g_KeyInfo.Val &= KEY_VAL;
      g_KeyInfo.Status = (PRESS_KEY_UP|KEY_TIME_SHORT)>>8;        
      g_uiKeyCode = MSG_KEY|(g_KeyInfo.Status<<8)|g_KeyInfo.Val;
     }
    }
    g_KeyInfo.Val = KEY_NULL;
    g_KeyInfo.Status        =        0;
    g_KeyInfo.Duration = 0;
    g_KeyInfo.Interval = 0;
    Set_Key_Release();
    return;   
  }

  if(m_ucKeyCode == g_KeyInfo.Val)//相同按键按下
  {
   if(If_Key_Process_Once())//如果该按键没有长按功能就退出
    return;

    if(F_KEY_SCAN_KICK)//F_Sys_2msec_kick 是定时器2ms定时标志
    {
     F_KEY_SCAN_KICK = 0;
     g_KeyInfo.Duration++;
     g_KeyInfo.Interval++;
    }

   if(g_KeyInfo.Interval >= TICK_STILL_PRESSED_STEP)//消抖判断
   {
    if((g_KeyInfo.Duration > TICK_TH_LONG_PRESS)
     &&(g_KeyInfo.Duration < TICK_TH_STILL_PRESS))//是长按
    {
      if(g_KeyInfo.KeyHoldPeriod == LONG_PRESS_ONCE)
      {
       Set_Key_Process_Once();//当前按键没有长按功能
      }
      else
      {
       Set_Key_Process_Continue();//当前按键有长按功能
      }
      g_KeyInfo.Duration = g_KeyInfo.KeyHoldPeriod;
      g_KeyInfo.Interval = 0;
      g_KeyInfo.Val &= KEY_VAL;
      g_KeyInfo.Status = (PRESS_KEY_DOWN|KEY_TIME_LONG)>>8;
      g_uiKeyCode = MSG_KEY|(g_KeyInfo.Status<<8)|g_KeyInfo.Val;//发送长按消息
    }
    else//是短按
    {
      if(g_KeyInfo.KeyHoldPeriod == LONG_PRESS_NONE)
      {
       g_KeyInfo.Duration = g_KeyInfo.KeyHoldPeriod;
       g_KeyInfo.Interval = 0;
       g_KeyInfo.Val &= KEY_VAL;
       g_KeyInfo.Status = (PRESS_KEY_DOWN|KEY_TIME_SHORT)>>8;
       g_uiKeyCode = MSG_KEY|(g_KeyInfo.Status<<8)|g_KeyInfo.Val;//发送短按消息
       Set_Key_Process_Once();
      }
    }
   }
  }
  else//发现有按键按下
  {
    Set_Key_Release();
    g_KeyInfo.Val        = m_ucKeyCode;
    g_KeyInfo.Status        = 0;
    g_KeyInfo.Duration = 0;
    g_KeyInfo.Interval = 0;
    g_KeyInfo.KeyHoldPeriod = LONG_PRESS_NONE;
    for(m_ucKeyIndex=0;m_ucKeyIndex<Get_Max_Key();m_ucKeyIndex++)
    {
     if(c_aKeyParam_Tab[m_ucKeyIndex].KeyCodeIdx == g_KeyInfo.Val)//查找是哪一个按键
     {
       g_KeyInfo.KeyHoldPeriod = c_aKeyParam_Tab[m_ucKeyIndex].LongKeyPeriod;//获取按键是否支持长按功能
       break;
     }
    }
  }
}

#ifndef __KEY_SCAN_H__
#define __KEY_SCAN_H__

#define MSG_TYPE   0xf000//消息类型,按键,遥控等
#define MSG_ATTR   0x0f00//长按,短按,按键按下,按键弹起
#define MSG_NULL                 0xffff// 空消息
#define MSG_KEY                         0x1000// 按键消息
#define MSG_IR                                 0x2000//红外消息

#define PRESS_KEY_DOWN  (0<<9)//0x00  //按下时触发
#define PRESS_KEY_UP                  (1<<9)//弹起时触发
#define KEY_TIME_SHORT  (0<<8)//0x00  //短按
#define KEY_TIME_LONG          (1<<8)//长按
#define KEY_TIME        (1<<8)
#define KEY_VAL         0xff

#define Get_Msg_Type()      (g_uiKeyCode&MSG_TYPE)
#define Get_Key_Val()       (g_uiKeyCode&KEY_VAL)
#define If_Key_Time_Short() ((g_uiKeyCode&MSG_ATTR) == KEY_TIME_SHORT)
#define If_Key_Time_Long()  ((g_uiKeyCode&MSG_ATTR) == KEY_TIME_LONG)
#define Clr_Key()           (g_uiKeyCode = MSG_NULL)
#define Get_Key()           (g_uiKeyCode&(KEY_TIME|KEY_VAL))

#define TICK_MSEC10   5//该值根据需要调整(F_KEY_SCAN_KICK*5ms)
#define TICK_MSEC20   TICK_MSEC10*2
#define TICK_MSEC30   TICK_MSEC10*3
#define TICK_MSEC40   TICK_MSEC10*4
#define TICK_MSEC50   TICK_MSEC10*5
#define TICK_MSEC60   TICK_MSEC10*6
#define TICK_MSEC100  TICK_MSEC10*10
#define TICK_MSEC200  TICK_MSEC10*20
#define TICK_MSEC300  TICK_MSEC10*30
#define TICK_MSEC400  TICK_MSEC10*40
#define TICK_MSEC500  TICK_MSEC10*50
#define TICK_MSEC600  TICK_MSEC10*60  
#define TICK_MSEC800  TICK_MSEC10*80
#define TICK_MSEC1200 (TICK_MSEC10*120-50)
#define TICK_MSEC1500 (TICK_MSEC10*150-50)

#define TICK_STILL_PRESSED_STEP TICK_MSEC20                

#define TICK_TH_PRESS_WAIT      TICK_MSEC50
#define TICK_TH_SHORT_PRESS                   TICK_MSEC100
#define TICK_TH_LONG_PRESS             TICK_MSEC1200//TICK_MSEC500
#define TICK_TH_STILL_PRESS            TICK_MSEC1500//TICK_MSEC800

#define LONG_PRESS_NONE         0xffff
#define LONG_PRESS_ONCE         TICK_TH_STILL_PRESS
#define LONG_PRESS_HOLD_LONG    0
#define LONG_PRESS_HOLD_SHORT   (TICK_TH_LONG_PRESS-TICK_TH_PRESS_WAIT)

#define KEY_RELEASE          0x00
#define KEY_HOLD             0x01
#define KEY_PROCESS_ONCE     0x00
#define KEY_PROCESS_CONTINUE 0x02
#define Set_Key_Release()          g_KeyInfo.HoldOn = KEY_RELEASE
#define Set_Key_Process_Once()     g_KeyInfo.HoldOn = (KEY_HOLD|KEY_PROCESS_ONCE)
#define Set_Key_Process_Continue() g_KeyInfo.HoldOn = (KEY_HOLD|KEY_PROCESS_CONTINUE)
#define If_Key_Process_Once()     (g_KeyInfo.HoldOn == (KEY_HOLD|KEY_PROCESS_ONCE))
#define If_Key_Process_Continue() (g_KeyInfo.HoldOn == (KEY_HOLD|KEY_PROCESS_CONTINUE))
#define If_Key_Press_Release()    (g_KeyInfo.HoldOn == KEY_RELEASE)
#define If_Key_Press_Hold()       ((g_KeyInfo.HoldOn&KEY_HOLD) == KEY_HOLD)

#define F_KEY_SCAN_KICK  F_Sys_2msec_kick

typedef struct _KEY_INFO
{
UINT8 Val;
UINT8 HoldOn;
        UINT8        Status;
        UINT16        Duration;
        UINT16        Interval;   
UINT16 KeyHoldPeriod;
} KEY_INFO;

typedef struct
{
UINT8 KeyParam;
UINT8 KeyCode;
}KEY_PARAM_CONV;

typedef struct  
{
UINT8 KeyMax;
KEY_PARAM_CONV Cfg[16];
}KEY_GET_PARAM;

typedef struct
{
UINT8 KeyCodeIdx;
UINT16 LongKeyPeriod;
}KEY_PARAM;

extern KEY_INFO g_KeyInfo;
extern UINT16 g_uiKeyCode;

extern void Key_Scan(UINT8 m_ucKeyCode);

#endif

文件上传了
Keyourdev_584418KBEHSB.rar(文件大小:3K) (原文件名:Key.rar)

出0入0汤圆

发表于 2010-9-20 16:14:04 | 显示全部楼层
mark,up

出0入0汤圆

发表于 2010-11-9 21:38:22 | 显示全部楼层
找了好久,mark

出0入0汤圆

发表于 2010-11-11 08:37:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-11 10:35:05 | 显示全部楼层
好帖要顶

出0入0汤圆

发表于 2010-11-11 14:20:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-11 20:23:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-22 11:32:42 | 显示全部楼层
马克思

出0入0汤圆

发表于 2010-12-27 23:32:12 | 显示全部楼层
记号 作参考

出0入0汤圆

发表于 2010-12-28 23:02:46 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-12-29 13:06:03 | 显示全部楼层
饭要一口一口吃,留着以后吃

出0入0汤圆

发表于 2010-12-29 14:44:22 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-4-28 00:02:14 | 显示全部楼层
按键的学问还是蛮大的啊

出0入0汤圆

发表于 2011-5-20 21:59:59 | 显示全部楼层
收藏

出0入0汤圆

发表于 2011-5-21 08:41:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-21 10:45:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-22 12:13:04 | 显示全部楼层
好多。。看的头晕
不过还是要标记下

出0入0汤圆

发表于 2011-5-22 13:03:17 | 显示全部楼层
业余的经过。。
很好

出0入0汤圆

发表于 2011-5-23 20:00:50 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-5-23 20:49:35 | 显示全部楼层
jh

出0入0汤圆

发表于 2011-5-23 21:17:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-23 22:10:23 | 显示全部楼层
Mark

出90入10汤圆

发表于 2011-5-24 08:33:07 | 显示全部楼层
mark
按键处理

出0入0汤圆

发表于 2011-6-6 16:04:38 | 显示全部楼层
好东西啊,mark

出0入0汤圆

发表于 2011-6-6 17:05:45 | 显示全部楼层
mm

出0入0汤圆

发表于 2011-6-6 18:46:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-6 21:20:52 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-6-8 14:14:24 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2011-6-8 14:48:46 | 显示全部楼层
高手就是多.

出0入0汤圆

发表于 2011-6-8 15:17:54 | 显示全部楼层
好东东,支持了

出0入0汤圆

发表于 2011-6-8 18:24:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-8 21:31:05 | 显示全部楼层
mark

出0入24汤圆

发表于 2011-6-8 21:43:25 | 显示全部楼层
学习之!

出0入0汤圆

发表于 2011-6-8 22:01:24 | 显示全部楼层
状态机按键检测 mark

出0入0汤圆

发表于 2011-6-8 23:30:51 | 显示全部楼层
mark一下,以后会用到的

出0入0汤圆

发表于 2011-6-9 09:32:17 | 显示全部楼层
好长……

出0入0汤圆

发表于 2011-6-9 09:37:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 23:25:12 | 显示全部楼层
学习不错

出0入0汤圆

发表于 2011-6-11 12:19:28 | 显示全部楼层
好东西,思路借鉴一下

出0入0汤圆

发表于 2011-7-5 11:13:48 | 显示全部楼层
楼主的程序具体怎么用啊?我没有看明白,能在主函数举个例子吗?谢谢了先!

出0入0汤圆

发表于 2011-7-5 11:16:33 | 显示全部楼层
不错,状态机按键检测

出0入0汤圆

发表于 2011-7-5 12:25:49 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-7-5 12:52:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-5 14:46:00 | 显示全部楼层
思路很好,支持

出0入0汤圆

发表于 2011-7-5 17:21:17 | 显示全部楼层
我有问题请教
1、
//应用代码片段---------------------------------------------------------------------------------------
以下的代码是不是都写在主函数中呢?如果在主函数中,哪个结构是不是应该用extern 声明呢?
2、在主函数中,键值是不是保存在CurKey?怎么样写不同键值做不同处理函数呢?

以前没有这样写过,觉得这个处理很好,想学习下,麻烦楼主或者各位大侠回复以下啊!

出0入0汤圆

发表于 2011-7-5 18:36:29 | 显示全部楼层
我在上课的一个项目里也是用定时器检测按键的 ,同时是有长按和短按,(通过标记已经按下但没抬起,抬起过没按下,抬起过又按下)
结果由于不知道main的运行时间(各种外部通信  delay 1-4ms 好多之后我不确定多久能跑一次。。)
判断按键时间都是用>=。。。不敢用=-
现在看看大婶是怎么做的。~~

出0入0汤圆

发表于 2011-7-6 12:49:37 | 显示全部楼层
学习中。

出0入0汤圆

 楼主| 发表于 2011-7-8 01:31:35 | 显示全部楼层
1 以下代码当然不是写在主函数中,那是好几个函数。不觉得需要extern声明。
2 具体键值的处理用这个函数:BYTE KeyDownCallBack(WORD Key, WORD Times),主函数只需要关心 g_DownKey 的值就可以了。实际上相当于有两个线程在工作,中断函数为一个线程,主程序为另一个线程,两个线程之间靠全局变量 g_DownKey 交换数据。这样主程序就只管处理键按下后的事情了,至于键盘扫描就交由定时中断处理,对于主程序来说可以当它不存在。

出0入0汤圆

发表于 2011-7-8 08:05:41 | 显示全部楼层
mark 按键处理

出0入0汤圆

发表于 2011-7-8 08:38:56 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2011-7-8 08:50:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-8 23:46:53 | 显示全部楼层
if(pInfo->KeyDownCallBack)
if(pInfo->KeyUPCallBack)
这个是什么用法呢?
给地址吗?
用途是?

BYTE KeyDownCallBack(WORD Key, WORD Times)
{
    switch(Key)
    {
    case _KEY_F2:
        if(Times < 200)             //长按 2s
        {
            return _REENTER;        //2s内允许长按
        }
        break;

    case _KEY_CLR_CNTR:
        if(Times < 1000)            //四个键长按10s
        {
            return _REENTER;        //允许长按
        }

    default:
        break;
    }

    g_DownKey = Key;                //输出按键信息, 给主循环处理. 这个回调函数是由定时中断中的代码调用的.
    return _NO_REENTER;             //其余键, 不允许长按
}
_KEY_F2如果现在长按住了。值还小与200的话?
值返回一个长按回复。然后break?
我想问一下,这个break是跳出switch还是跳出这个函数呢?我感觉是跳出这个switch 接下来还会执行

g_DownKey = Key;                //输出按键信息, 给主循环处理. 这个回调函数是由定时中断中的代码调用的.
    return _NO_REENTER;
求解?

出0入0汤圆

 楼主| 发表于 2011-7-9 00:15:49 | 显示全部楼层
if(pInfo->KeyDownCallBack)  
if(pInfo->KeyUPCallBack)  
是判断函数指针是否为空,若为空就不处理。比如没有KeyUPCallBack就可以不处理键抬起的事件。
如果小于200,不改变当前状态,然后返回,等下次进入键扫描中断,一般我把中断定时间隔设置为10ms.
最后一个:是的。

出0入0汤圆

发表于 2011-7-9 01:36:47 | 显示全部楼层
先mark再看..

出0入0汤圆

发表于 2011-7-9 01:49:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-9 05:59:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-9 08:13:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-9 09:43:12 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-7-9 10:46:46 | 显示全部楼层
mark.

出0入0汤圆

发表于 2011-7-11 18:31:43 | 显示全部楼层
回复【159楼】nicksean  不务正业
-----------------------------------------------------------------------回复【159楼】nicksean  不务正业
-----------------------------------------------------------------------

你说的空?是代表 这个为NULL吗
但是 你也没有进行处理这个指针啊。

还有,
BYTE KeyDownCallBack(WORD Key, WORD Times)  
{  
    switch(Key)  
    {  
    case _KEY_F2:  
        if(Times < 200)             //长按 2s  
        {  
            return _REENTER;        //2s内允许长按  
        }  
        break;  

    case _KEY_CLR_CNTR:  
        if(Times < 1000)            //四个键长按10s  
        {  
            return _REENTER;        //允许长按  
        }  

    default:  
        break;  
    }  

    g_DownKey = Key;                //输出按键信息, 给主循环处理. 这个回调函数是由定时中断中的代码调用的.  
    return _NO_REENTER;             //其余键, 不允许长按  
}
这个break;语句我现在还不明白 是跳出switch 还是跳出函数?
是不是 一个函数return 了一次后,不会再执行return第二次。
我c的基础差。有人解释一下吗
头像被屏蔽

出0入0汤圆

发表于 2011-7-11 19:36:28 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2011-7-11 21:13:07 | 显示全部楼层
状态机按键检测

出0入0汤圆

发表于 2011-7-11 21:28:31 | 显示全部楼层
mark...

出0入0汤圆

发表于 2011-7-12 13:33:23 | 显示全部楼层
回复【169楼】hackthree  
-----------------------------------------------------------------------

为什么都喜欢mark呢

可以解决一下问题

提一下问题不是挺好的吗

出0入0汤圆

发表于 2011-8-23 13:00:40 | 显示全部楼层
太精彩了 不错

出0入0汤圆

发表于 2011-8-26 11:28:10 | 显示全部楼层
可能按键人人都做过,但要总结好不容易。楼主辛苦了

出0入0汤圆

发表于 2011-9-8 09:58:37 | 显示全部楼层
强势围观,记号学习!真的不错,得好好学

出0入0汤圆

发表于 2011-9-8 19:00:11 | 显示全部楼层
好复杂

出0入0汤圆

发表于 2011-9-29 15:33:54 | 显示全部楼层
不知道,那个time是那得到的,如何判断是否是长按,void (*KeyUpCallBack)(WORD); 有实例吗?

最好是有判断按键抬起为一个完整动作,然后通过g_DownKey让主程序轮训到有动作键产生,然后主程序处理键对应的动作。

出0入0汤圆

发表于 2011-10-31 12:19:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-4 14:42:26 | 显示全部楼层
记号

出0入0汤圆

发表于 2011-11-5 00:38:30 | 显示全部楼层
果断MARK

出0入0汤圆

发表于 2011-11-5 11:59:00 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2011-11-6 19:22:13 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-11-6 19:42:01 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2011-11-8 22:44:33 | 显示全部楼层
我还是看不懂啊,哎。

出0入0汤圆

发表于 2012-5-1 23:58:56 | 显示全部楼层
怎么回事,乱码?

出0入0汤圆

发表于 2012-5-2 11:49:33 | 显示全部楼层
看起来还可以,具体的效果有待试验。

出0入0汤圆

发表于 2012-5-2 13:01:24 | 显示全部楼层
本帖子第一页怎么一下子多出了这么多个 “&nbsp; ”   ,看起来真不习惯。

出0入0汤圆

发表于 2012-7-15 17:02:02 | 显示全部楼层
mark,先去看看&nbsp

出0入0汤圆

发表于 2014-4-24 08:57:15 | 显示全部楼层
没看明白,&nbsp是啥意思

出0入0汤圆

发表于 2014-4-24 23:57:54 | 显示全部楼层
赞一个,最近移植在研究结构体、指针、状态机,这帖子刚好合适啊,谢谢LZ

出0入0汤圆

发表于 2014-4-25 12:48:14 | 显示全部楼层
我只笑笑.

出0入0汤圆

发表于 2014-4-25 12:48:44 | 显示全部楼层

出0入0汤圆

发表于 2021-7-13 17:37:56 | 显示全部楼层
全是乱码呢?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2023-1-31 18:25

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

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