状态机按键的参考程序?

[复制链接]
7554|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的效率不高。
 楼主| lium 发表于 2021-7-7 20:06 | 显示全部楼层
lizye 发表于 2021-7-7 20:11 | 显示全部楼层
源码区找找吧,肯定有
午夜粪车 发表于 2021-7-7 20:13 | 显示全部楼层

状态机按键 是老生常谈的问题了,论坛中有很多资料的,楼主再找找看呗。。。
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
 楼主| lium 发表于 2021-7-7 20:17 | 显示全部楼层
其实还是不大明白,我再琢磨琢磨吧,多谢了哈
zhengshuai888 发表于 2021-7-10 13:45 来自手机 | 显示全部楼层
这个很简单的,多看一下别人的代码,找点思路。
勇敢的大白菜 发表于 2021-7-14 16:02 | 显示全部楼层
多看看别人的代码,可以知道很多东西的。
aple0807 发表于 2021-7-30 13:23 | 显示全部楼层
本帖最后由 aple0807 于 2021-7-30 13:26 编辑
  1. typedef struct
  2.         {
  3.                 uint8_t read_flt_cnt; //采样滤波计数
  4.                 uint8_t b_first_key;  //首个按键
  5.                 uint16_t found_time_cnt;
  6.                 uint16_t lost_time_cnt;
  7.                 uint16_t keep_time_cnt;
  8.                 uint32_t val;
  9.                 uint32_t old;
  10.                 uint32_t edge;
  11.                 uint32_t found_edge;
  12.                 uint32_t lost_edge;
  13.                 uint32_t read;
  14.                 uint32_t read_old;
  15.         } key_type;
  1. /*-------------------------------------------------------------*
  2. * called by timer isr
  3. *--------------------------------------------------------------*/
  4. void key_st_sample(key_type *key, uint8_t flt_sv, uint32_t key_read)
  5. {
  6.         if (key_read == key->read_old)
  7.         {
  8.                 key->read_flt_cnt++;
  9.                 if (key->read_flt_cnt >= flt_sv)
  10.                 {
  11.                         key->read = key_read;
  12.                 }
  13.         }
  14.         else
  15.         {
  16.                 key->read_flt_cnt = 0;
  17.         }

  18.         key->read_old = key_read;
  19. }

  20. /*-------------------------------------------------------------*
  21. * called by app
  22. *--------------------------------------------------------------*/
  23. void key_st_handle(key_type *key, uint8_t time_pulse)
  24. {
  25.         uint32_t key_now;

  26.         key_now = key->read;
  27.         key->val = key_now;
  28.         key->edge = key->val ^ key->old;
  29.         key->found_edge = key->edge & key_now;
  30.         key->lost_edge = key->edge & key->old;

  31.         if (key_now)
  32.         {
  33.                 key->lost_time_cnt = 0;
  34.                 if (time_pulse)
  35.                 {
  36.                         if (key->found_time_cnt < INT16_MAX)
  37.                                 key->found_time_cnt++;
  38.                         key->keep_time_cnt++;
  39.                 }
  40.         }
  41.         else
  42.         {
  43.                 key->found_time_cnt = 0;
  44.                 if (time_pulse)
  45.                 {
  46.                         if (key->lost_time_cnt < INT16_MAX)
  47.                                 key->lost_time_cnt++;
  48.                         key->keep_time_cnt++;
  49.                 }
  50.         }

  51.         if (key->edge)
  52.                 key->keep_time_cnt = 0;

  53.         if (key_now && (0 == key->old))
  54.         {
  55.                 key->b_first_key = 1;
  56.         }
  57.         else
  58.         {
  59.                 key->b_first_key = 0;
  60.         }

  61.         key->old = key_now;
  62. }
我们常用的多键值程序,分ISR采集和应用处理两部分,key_val的每个bit位作为一个按键的状态。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

915

主题

9578

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部