stm8s105K4 多按键,多功能 长短按键 区分 有限状态机

2019-12-11 18:33发布

自己测试没有什么问题,求鉴定
这个按键要每20MS 调用一下,然后用


原程序如下

/********************************
用之前把IO设置为上拉输入后每20ms调用一次就行了
每次调用 Skcankeystep()后再测试什么按键

按键处理  

*****/


#ifndef _stm8_key
#define _stm8_key 1
#include "stm8s207r.h"
#define key1   0
#define key2   1
#define key3   2
#define key4   3
#define Keyport PB_IDR
#define Key1up    (Keyport&(1<<key1))
#define Key1down  !(Keyport&(1<<key1))
#define Key2up    (Keyport&(1<<key2))
#define Key2down  !(Keyport&(1<<key2))
#define Key3up    (Keyport&(1<<key3))
#define Key3down  !(Keyport&(1<<key3))
#define Key4up    (Keyport&(1<<key4))
#define Key4down  !(Keyport&(1<<key4))
#define Key_mode_scan  1
#define Key_mode_delay  2
#define Key_mode_valu  3
#define Key_mode_K4UP 4


#define GIC_Key_Valu_Key1down 1
#define GIC_Key_Valu_Key2down 2
#define GIC_Key_Valu_Key3down 3
#define GIC_Key_Valu_Key4down 4

#define GIC_Key_Valu_Key1up  5
#define GIC_Key_Valu_Key2up  6
#define GIC_Key_Valu_Key3up  7
#define GIC_Key_Valu_Key4_long_up  8

#define  GIC_Key_Valu_Key4_short_up  9
#define  GIC_Key_Longkey_Delaytiem  250  //0.02S*250 =5s
#define  GIC_Key_Step_time          300

#define  GIC_Nokey   0;
#define  GIC_Cleardelay_time 0;
unsigned long int   GLV_Key_Scan_time;

unsigned int GIV_Key_valu;
unsigned int GIV_Key_Mode_Step=Key_mode_scan;
unsigned int GIV_Key4_delaytime ;


void Skcankey(void)
{
if(Key4down)
{
  GIV_Key_valu=4;
}
if(Key3down)
{
  GIV_Key_valu=3;
}
if(Key2down)
{
  GIV_Key_valu=2;
}
if(Key1down)
{
  GIV_Key_valu=1;
}
if(Key1up&&Key2up&&Key3up&&Key4up)
{
{
  GIV_Key_valu=5;
}
}


}
/**
以下程序是为了测试有状态机测试写的
2011年12月25日21时34分39秒
ver 01


*/
void Skcankeystep (void)
{
  switch(GIV_Key_Mode_Step)
  {
          case Key_mode_scan:
        {
           if (Key4down||Key3down||Key2down||Key1down)
          {
            if(Key1down)
       {
                                                GIV_Key_valu=GIC_Key_Valu_Key1down;
        }
                                if(Key2down)
        {
           GIV_Key_valu=GIC_Key_Valu_Key2down;
        }
                                if(Key3down)
        {
            GIV_Key_valu=GIC_Key_Valu_Key3down;
         }
                                 if(Key4down)
         {
           GIV_Key_valu=GIC_Key_Valu_Key4down;
          }
                                        GIV_Key_Mode_Step=Key_mode_delay;
          }       
   
         else
    {
                  GIV_Key_valu=GIC_Nokey;//把上次的值清去 2011年12月26日09时24分37秒test
                }               
         
           break;
        }
                  case Key_mode_delay://
        {  
          if (Key4down||Key3down||Key2down||Key1down)
          {
            if(Key1down)
       {
                                                GIV_Key_valu=GIC_Key_Valu_Key1down;
                                                GIV_Key_Mode_Step=Key_mode_valu;
        }
                                if(Key2down)
        {
           GIV_Key_valu=GIC_Key_Valu_Key2down;
                                         GIV_Key_Mode_Step=Key_mode_valu;
        }
                                if(Key3down)
        {
            GIV_Key_valu=GIC_Key_Valu_Key3down;
                                                GIV_Key_Mode_Step=Key_mode_valu;
         }
                                 if(Key4down)
         {
           GIV_Key_valu=GIC_Key_Valu_Key4down;
                                         
                                         GIV_Key_Mode_Step=Key_mode_valu;
                                         GIV_Key4_delaytime=GIC_Cleardelay_time;
          }
                                       
                }
               
                 else
    { GIV_Key_valu=GIC_Nokey;
                  GIV_Key_Mode_Step=Key_mode_scan;//这个是防止按键太快时
                        //在状态2中一直等待
                }       
        break;
        }
                  case Key_mode_valu:
        {
          switch(GIV_Key_valu)
        {
          case GIC_Key_Valu_Key1down:
          {         if(Key1up)
        {
            GIV_Key_valu=GIC_Key_Valu_Key1up;
                                                GIV_Key_Mode_Step=Key_mode_scan;
         }
                                 break;
                }
                case GIC_Key_Valu_Key2down:
          {         if(Key2up)
        {
            GIV_Key_valu=GIC_Key_Valu_Key2up;
                                                GIV_Key_Mode_Step=Key_mode_scan;
         }
                                 break;
                }
                case GIC_Key_Valu_Key3down:
          {         if(Key3up)
        {
            GIV_Key_valu=GIC_Key_Valu_Key3up;
                                                GIV_Key_Mode_Step=Key_mode_scan;
         }
                                 break;
                }
                                case GIC_Key_Valu_Key4down:
          {          GIV_Key4_delaytime++;
                   if(Key4down&&(GIV_Key4_delaytime>GIC_Key_Longkey_Delaytiem))
        {
            
                                                GIV_Key_Mode_Step=Key_mode_K4UP;
                                                GIV_Key4_delaytime=GIC_Cleardelay_time;
         }
                                 if(Key4up&&(GIV_Key4_delaytime<GIC_Key_Longkey_Delaytiem))
                         {
                         GIV_Key_valu=GIC_Key_Valu_Key4_short_up;
                         GIV_Key_Mode_Step=Key_mode_scan;
                         GIV_Key4_delaytime=GIC_Cleardelay_time; //n2011年12月25日23时03分36秒 test ok
                         }
                               
                       
                                 break;
                }
          
        }
         
          break;
        }
         case Key_mode_K4UP:
{
  if(Key4up)
  {
     GIV_Key_valu=GIC_Key_Valu_Key4_long_up;
                 GIV_Key_Mode_Step=Key_mode_scan;
                 GIV_Key4_delaytime=GIC_Cleardelay_time;
  }
     break;
}
        }
}
/*
状态机测试程序  2011年12月26日09时04分54秒

*/

#endif
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
17条回答
Eiman
2019-12-13 01:33
这个如何呢?思路比较清晰!
#ifdef SARADC_KEY_ENABLE//Add by EimanFeng 2013-07-03
#define KEY_SCAN_CFG_1  KEY_NEXT,
#define KEY_SCAN_CFG_2  KEY_PREV,
#define KEY_SCAN_CFG_3  KEY_VOLUP,
#define KEY_SCAN_CFG_4  KEY_VOLDN,
#define KEY_SCAN_CFG_5  KEY_ENTER,
#define KEY_SCAN_CFG_6  
#define KEY_SCAN_CFG_7  
#define KEY_SCAN_CFG_8  
#define KEY_SCAN_CFG_9  
#define KEY_SCAN_CFG_10

UINT8 c_aKeyParam_Tab[] =
{
KEY_SCAN_CFG_1  KEY_SCAN_CFG_2  KEY_SCAN_CFG_3  KEY_SCAN_CFG_4  KEY_SCAN_CFG_5
KEY_SCAN_CFG_6  KEY_SCAN_CFG_7  KEY_SCAN_CFG_8  KEY_SCAN_CFG_9  KEY_SCAN_CFG_10
};

KEY_INFO g_KeyInfo = {KEY_NULL,KEY_EVENT_IDLE,0};
UINT16 g_uiKeyCode = MSG_BOX_NULL;

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

void Key_Event(UINT8 m_ucKeyCode)
{
UINT8 m_ucKeyIndex;

switch(g_KeyInfo.Status)
{
  case KEY_EVENT_IDLE:
   if(m_ucKeyCode == KEY_NULL)
   {
    break;
   }
   g_KeyInfo.Duration = 0;
   g_KeyInfo.Val        = m_ucKeyCode;
   for(m_ucKeyIndex=0;m_ucKeyIndex<Get_Max_Key();m_ucKeyIndex++)
   {
    if(c_aKeyParam_Tab[m_ucKeyIndex] == g_KeyInfo.Val)
    {
     break;
    }
   }
   if(m_ucKeyIndex == Get_Max_Key())
   {
    g_KeyInfo.Val = KEY_NULL;
    break;
   }
   g_KeyInfo.Status = KEY_EVENT_CHK_DISTURB;
   break;

  case KEY_EVENT_CHK_DISTURB:
   if(m_ucKeyCode == g_KeyInfo.Val)
   {
    g_KeyInfo.Status = KEY_EVENT_IS_PRESS;
   }
   else
   {
    g_KeyInfo.Status = KEY_EVENT_IDLE;
   }
   break;

  case KEY_EVENT_IS_PRESS:
   //Set_Key(MSG_KEY|(PRESS_KEY_DOWN|KEY_PRESS_SHORT)|g_KeyInfo.Val);
   g_KeyInfo.Status = KEY_EVENT_CHK_HOLD;
   g_KeyInfo.Duration = 0;
   break;

  case KEY_EVENT_CHK_HOLD:
   if(m_ucKeyCode == g_KeyInfo.Val)
   {
    if(++g_KeyInfo.Duration >= TICK_TH_LONG_PRESS)
    {
     Set_Key(MSG_KEY|(PRESS_KEY_DOWN|KEY_PRESS_LONG)|g_KeyInfo.Val);
     g_KeyInfo.Status = KEY_EVENT_CHK_CONTINUE;
     g_KeyInfo.Duration = 0;
    }
   }
   else
   {
    goto KEY_RELEASE_LABLE;//g_KeyInfo.Status = KEY_EVENT_CHK_RELEASE;
   }
   break;
   
  case KEY_EVENT_CHK_CONTINUE:
   if(m_ucKeyCode == g_KeyInfo.Val)
   {
    if(++g_KeyInfo.Duration >= TICK_TH_LONG_PRESS)
    {
     Set_Key(MSG_KEY|(PRESS_KEY_DOWN|KEY_PRESS_LONG|KEY_HOLD_CNT_LONG)|g_KeyInfo.Val);
     g_KeyInfo.Duration = 0;
    }
    else
    {
     if((g_KeyInfo.Duration%TICK_TH_SHORT_PRESS) == 0)
     {
      Set_Key(MSG_KEY|(PRESS_KEY_DOWN|KEY_PRESS_LONG|KEY_HOLD_CNT_SHORT)|g_KeyInfo.Val);
     }
    }
    break;
   }
   
KEY_RELEASE_LABLE:   
  case KEY_EVENT_CHK_RELEASE:
   if((g_KeyInfo.Status == KEY_EVENT_CHK_HOLD) && (g_KeyInfo.Duration < TICK_TH_LONG_PRESS))
   {
    Set_Key(MSG_KEY|(PRESS_KEY_DOWN|KEY_PRESS_SHORT)|g_KeyInfo.Val);
    g_KeyInfo.Status = KEY_EVENT_IDLE;
    break;
   }
   Set_Key(MSG_KEY|(PRESS_KEY_UP|KEY_PRESS_SHORT)|g_KeyInfo.Val);
   g_KeyInfo.Status = KEY_EVENT_IDLE;
   break;
}
}

void Key_Proc(void)
{
UINT16 m_uiKeyCodeHead;
static uint32 m_ulKeuTick=0;

if(get_system_ms()-m_ulKeuTick < 10L)
{
  return;
}
m_ulKeuTick = get_system_ms();

Clr_Key();
Key_Event(Get_AdKeyCode());

m_uiKeyCodeHead = Get_Msg_Type();
if((m_uiKeyCodeHead != MSG_KEY)&&(m_uiKeyCodeHead != MSG_IR))
{
  return;
}
        lastProcessTick = get_system_ms();
        if(display_open() == TRUE)
        {
        Clr_Key();
        }
if(If_Key_Null())
{
  return;
}

switch(Get_Key_Val())
{
   case KEY_NEXT:
    if(If_Key_Press_Short())
    {
     UserCmd = USER_CMD_NEXT;
     break;
    }
    if(If_Key_Hold_Cnt_Short())
    {
     UserCmd = USER_CMD_FFWD;
     break;
    }
    if(If_Key_Hold_Cnt_Long())
    {
     UserCmd = USER_CMD_FFWD;
     break;
    }
    break;

   case KEY_PREV:
    if(If_Key_Press_Short())
    {
     UserCmd = USER_CMD_PREV;
     break;
    }
    if(If_Key_Hold_Cnt_Short())
    {
     UserCmd = USER_CMD_FBWD;
     break;
    }
    if(If_Key_Hold_Cnt_Long())
    {
     UserCmd = USER_CMD_FBWD;
     break;
    }
    break;

   case KEY_VOLUP:
    if(If_Key_Press_Short())
    {
     UserCmd = USER_CMD_VOLUP;
     break;
    }
    if(If_Key_Press_Long())
    {
     UserCmd = USER_CMD_VOLUP;
     break;
    }
    if(If_Key_Hold_Cnt_Short())
    {
     UserCmd = USER_CMD_VOLUP;
     break;
    }
    if(If_Key_Hold_Cnt_Long())
    {
     UserCmd = USER_CMD_VOLUP;
     break;
    }
    break;

   case KEY_VOLDN:
    if(If_Key_Press_Short())
    {
     UserCmd = USER_CMD_VOLDN;
     break;
    }
    if(If_Key_Press_Long())
    {
     UserCmd = USER_CMD_VOLDN;
     break;
    }
    if(If_Key_Hold_Cnt_Short())
    {
     UserCmd = USER_CMD_VOLDN;
     break;
    }
    if(If_Key_Hold_Cnt_Long())
    {
     UserCmd = USER_CMD_VOLDN;
     break;
    }
    break;
   
   case KEY_ENTER:
    if(If_Key_Press_Short())
    {
     UserCmd = USER_CMD_ENTER;
     break;
    }
    if(If_Key_Press_Long())
    {
     UserCmd = USER_CMD_MENU;
     break;
    }
    break;
   
   default:
    break;
}
}
#endif

一周热门 更多>