打印

状态机按键的参考程序?

[复制链接]
7265|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lium|  楼主 | 2021-7-7 19:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家有没有状态机按键的参考程序?

使用特权

评论回复
沙发
pengf| | 2021-7-7 19:58 | 只看该作者
这个很多吧

使用特权

评论回复
板凳
lium|  楼主 | 2021-7-7 20:01 | 只看该作者
以前按键都是用延时程序来判断的

使用特权

评论回复
地板
ousj| | 2021-7-7 20:04 | 只看该作者

这样CPU的效率不高。

使用特权

评论回复
5
lium|  楼主 | 2021-7-7 20:06 | 只看该作者
是啊

使用特权

评论回复
6
lizye| | 2021-7-7 20:11 | 只看该作者
源码区找找吧,肯定有

使用特权

评论回复
7
午夜粪车| | 2021-7-7 20:13 | 只看该作者

状态机按键 是老生常谈的问题了,论坛中有很多资料的,楼主再找找看呗。。。

使用特权

评论回复
8
zhenykun| | 2021-7-7 20:15 | 只看该作者
#include "KeyBoard.h"
#include "AS1.h"

//unsigned int msCount;
#define KeyBuffLen 8
struct Struct_KeyBoardBuff
{
  uchar buff[KeyBuffLen];
  uchar in;
  uchar out;
}Key;
enum KeyFSM_Enum
{
  _Key_Idle=0,
  _Key1_down,
  _Key1_press,
  _Key1_up,
  _Key2_down,
  _Key2_press,
  _Key2_up,
  _Key_confirm,
};

void KeyBoardInit(void)
{
Key.in=0;
Key.out=0;
}
uchar ReadKey(void)
{
  uchar Value;
  if (Key.out!=Key.in)
  {
    Value=Key.buff[Key.out++];
    if (Key.out>=KeyBuffLen)
    {
      Key.out=0;
    }
  }
  else
  {
    Value=KeyNull;
  }
  return(Value);
}
uchar JudgeKey(uchar key)
{
  uchar i,count=0;
  for (i=0;i<6 ;i++ )
  {
    if ((key&0x01)==0)count++;
    key=key>>1;
  }
  return(count);
}
void KeyIn(void)
{
  static uchar Key_Input=0;
  static uchar volatile step=0;
  //Put the code get the Key_Value
  uchar NewKey=KEY_PORT&0x3f;
  //---------------------------
  uchar num=JudgeKey(NewKey);
  switch(step)
  {
    case _Key_Idle:
    {
      switch (num)
      {
        case 1:
        {
          Key_Input=NewKey;
          step=_Key1_down;
          break;
        }
        case 2:
        {
          Key_Input=NewKey;
          step=_Key2_down;
          break;
        }
        default:
        {
          break;
        }
      }
      break;
    }
    case _Key1_down:
    {
      switch (num)
      {
        case 1:
        {
          if(NewKey==Key_Input)
            step=_Key1_press;
          else
            step=_Key_Idle;
          break;
        }
        case 2:
        {
          Key_Input=NewKey;
          step=_Key2_down;
          break;
        }
        default:
        {
          step=_Key_Idle;
          break;
        }
      }
      break;
    }
    case _Key1_press:
    {
      switch (num)
      {
        case 1:
        {
          if(NewKey!=Key_Input)
            step=_Key1_up;
          break;
        }
        case 2:
        {
          Key_Input=NewKey;
          step=_Key2_down;
          break;
        }
        default:
        {
          step=_Key1_up;
          break;
        }
      }
      break;
    }
    case _Key1_up:
    {
      switch (num)
      {
        case 1:
        {
          if(NewKey==Key_Input)
            step=_Key1_press;
          else
            step=_Key_confirm;
          break;
        }
        case 2:
        {
          Key_Input=NewKey;
          step=_Key2_down;
          break;
        }
        default:
        {
          step=_Key_confirm;
          break;
        }
      }
      break;
    }
    case _Key2_down:
    {
      if(NewKey==Key_Input)
        step=_Key2_press;
      else
        step=_Key_Idle;
      break;
    }
    case _Key2_press:
    {
      if (num==0)
        step=_Key2_up;
      break;
    }
    case _Key2_up:
    {
      if (num==0)
        step=_Key_confirm;
      break;
    }
    default:
    {
      step=_Key_Idle;
      break;
    }
  }
  if (step==_Key_confirm)
  {
    step=_Key_Idle;
    if (Key_Input!=0)
    {
      Key.buff[Key.in++]=Key_Input;
      if (Key.in>=KeyBuffLen)
      {
        Key.in=0;
      }
    }
  }
}


void Key_Board_Test(void)
{
  uchar key;
  key=ReadKey();
    switch (key)
    {
      case KeyUp:
      {
        AS1_SendString("Up.");
        break;
      }
      case KeyDown:
      {
        AS1_SendString("Down.");
        break;
      }
      case KeyAdd:
      {
        AS1_SendString("Add.");
        break;
      }
      case KeySub:
      {
        AS1_SendString("Sub.");
        break;
      }
      case KeyEnter:
      {
        AS1_SendString("Enter.");
        break;
      }
      case KeyReturn:
      {
        AS1_SendString("Return.");
        break;               
      }
      case KeyLr:
      {
        AS1_SendString("LR.");
        break;
      }
      default:
      {
        //AS1_SendString("None.");
        break;
      }
    }
}

文件Keyboard.h

#ifndef _Key_Board_h_
#define _Key_Board_h_

#define KEY_PORT PORTA

#define KeyUp 0x3e
#define KeyDown 0x3d
#define KeyAdd 0x3b
#define KeySub 0x37
#define KeyEnter 0x2f
#define KeyReturn 0x1f
#define KeyLr 0x33
#define KeyNull 0xff
typedef unsigned char uchar;
extern unsigned int msCount;

extern void KeyBoardInit(void);
extern unsigned char ReadKey(void);
extern void KeyIn(void);
extern void Key_Board_Test(void);

#endif

使用特权

评论回复
9
lium|  楼主 | 2021-7-7 20:17 | 只看该作者
其实还是不大明白,我再琢磨琢磨吧,多谢了哈

使用特权

评论回复
10
zhengshuai888| | 2021-7-10 13:45 | 只看该作者
这个很简单的,多看一下别人的代码,找点思路。

使用特权

评论回复
11
勇敢的大白菜| | 2021-7-14 16:02 | 只看该作者
多看看别人的代码,可以知道很多东西的。

使用特权

评论回复
12
aple0807| | 2021-7-30 13:23 | 只看该作者
本帖最后由 aple0807 于 2021-7-30 13:26 编辑
 typedef struct
        {
                uint8_t read_flt_cnt; //采样滤波计数
                uint8_t b_first_key;  //首个按键
                uint16_t found_time_cnt;
                uint16_t lost_time_cnt;
                uint16_t keep_time_cnt;
                uint32_t val;
                uint32_t old;
                uint32_t edge;
                uint32_t found_edge;
                uint32_t lost_edge;
                uint32_t read;
                uint32_t read_old;
        } key_type;
/*-------------------------------------------------------------*
* called by timer isr
*--------------------------------------------------------------*/
void key_st_sample(key_type *key, uint8_t flt_sv, uint32_t key_read)
{
        if (key_read == key->read_old)
        {
                key->read_flt_cnt++;
                if (key->read_flt_cnt >= flt_sv)
                {
                        key->read = key_read;
                }
        }
        else
        {
                key->read_flt_cnt = 0;
        }

        key->read_old = key_read;
}

/*-------------------------------------------------------------*
* called by app
*--------------------------------------------------------------*/
void key_st_handle(key_type *key, uint8_t time_pulse)
{
        uint32_t key_now;

        key_now = key->read;
        key->val = key_now;
        key->edge = key->val ^ key->old;
        key->found_edge = key->edge & key_now;
        key->lost_edge = key->edge & key->old;

        if (key_now)
        {
                key->lost_time_cnt = 0;
                if (time_pulse)
                {
                        if (key->found_time_cnt < INT16_MAX)
                                key->found_time_cnt++;
                        key->keep_time_cnt++;
                }
        }
        else
        {
                key->found_time_cnt = 0;
                if (time_pulse)
                {
                        if (key->lost_time_cnt < INT16_MAX)
                                key->lost_time_cnt++;
                        key->keep_time_cnt++;
                }
        }

        if (key->edge)
                key->keep_time_cnt = 0;

        if (key_now && (0 == key->old))
        {
                key->b_first_key = 1;
        }
        else
        {
                key->b_first_key = 0;
        }

        key->old = key_now;
}
我们常用的多键值程序,分ISR采集和应用处理两部分,key_val的每个bit位作为一个按键的状态。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

915

主题

9578

帖子

3

粉丝