单片机 按钮——1

来源:互联网 发布:win10拍照软件 编辑:程序博客网 时间:2024/06/05 19:38

#include<reg52.h> 
                 
#define u16 unsigned int
#define u8 unsigned char
#define u32 unsigned long
#define TIMER0_BASE_INTERVAL 50 
#define HIBYTE ((65536-10000)/256)
#define LIBYTE ((65536-10000)%256)

/*Define Key Value */
#define KEY_VALUE_0 0x3f
#define KEY_VALUE_1 0x06
#define KEY_VALUE_2 0x5b
#define KEY_VALUE_3 0x4f
#define KEY_VALUE_4 0x66
#define KEY_VALUE_5 0x6d
#define KEY_VALUE_6 0x7d
#define KEY_VALUE_7 0x07
#define KEY_VALUE_8 0x7f
#define KEY_VALUE_9 0x6f
#define KEY_VALUE_A 0x77
#define KEY_VALUE_B 0x7c
#define KEY_VALUE_C 0x39
#define KEY_VALUE_D 0x5e
#define KEY_VALUE_E 0x79
#define KEY_VALUE_F 0x71
#define KEY_VALUE_NULL 0x00

/*Define Key State  */
#define KEY_STATE_INIT  0
#define KEY_STATE_SHORT 1
#define KEY_STATE_LONG  2
#define KEY_STATE_HOLD  3
#define KEY_STATE_DOUBLE 4
#define KEY_STATE_TRIPLE 5


u8 code DSYCode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,   
0x7f,0x6f,0x77,0x7c,   
0x39,0x5e,0x79,0x71,
0x00};

u8 Key[3];
u8 gu8_CurrentKey = 0xFF;
u8 PreKeyNo = 16;
u8 KeyNo = 16;
u8 gu8_LEDFlag = 0;
u8 gu8_Status = 0;
u16 gu16_PressStayCount = 0;
u8 gu8_Interval = 0;
u32 gu32_GlobalTime = 0;
u8 gu8_SingleClickCount = 0;
u8 gu8_SecondFlag;
u8 gu8_DelayFlag = 0;
u16 gu16_SecondCount=0;
/*------------------------------------------------
                 Sub Menu
------------------------------------------------*/
/*For test*/
void Count()
{
 u8 i = 0;
 for(i;; i++)
 {
  P0 = DSYCode[i];
  if(i  == 15) i = 0;
 }
}

void ScanKeyNo()
{
 
  u8 Tmp;
  P1 = 0x0F;
  Tmp = P1 ^ 0x0F;
  switch(Tmp)  
  {
   case 1: KeyNo = 0;break;
   case 2: KeyNo = 1;break;
   case 4: KeyNo = 2;break;
   case 8: KeyNo = 3;break;
   default:  KeyNo = 16;
  }
  P1 = 0xF0;
  Tmp = (P1 ^ 0xF0) >> 4;
  switch(Tmp) 
  {
   case 1: KeyNo += 0;break;
   case 2: KeyNo += 4;break;
   case 4: KeyNo += 8;break;
   case 8: KeyNo += 12;
  }
  gu16_PressStayCount++;      //Counting how many times for once.
}

 

 

//==Define key return values ==//
/*
          1 case:Single Pressed---Show KeyNo
      Double Pressed---0x5b(Two)
      Trigon Pressed---P0=0x4f(Three)

     2(Long Pressed):function Count()
     3(Hold Button):P0=0x00;
*/
void SetLEDValue()
{
  switch(gu8_Status)
  {
   case KEY_STATE_SHORT:
    gu8_CurrentKey = DSYCode[KeyNo];
    Key[gu8_SingleClickCount - 1] = KeyNo;
    break;
   case KEY_STATE_LONG:
     gu8_CurrentKey = ~(0x4e);
  
    break;
   case KEY_STATE_HOLD:    
    gu8_CurrentKey = 0x00;
    break;
  }
 gu8_LEDFlag = 0;
 gu8_Status = 0;
}
/*Status: 0(Invalid)
           1(Short Pressed)
  2(Long Pressed)
  3(Hold Button)
*/
void SetKeyStatusValue()
{

  ScanKeyNo();
  if(gu16_PressStayCount > 0 && gu16_PressStayCount < 2)
  {
  gu8_Status = 0;
  gu8_LEDFlag = 0;
  }
  else
  {
  if(3==gu16_PressStayCount )
  {
   gu8_SecondFlag =1;
   gu8_SingleClickCount++;
   gu8_Status = KEY_STATE_SHORT;
  }
  if(300 == gu16_PressStayCount)
  {
   gu8_Status = KEY_STATE_LONG;
  }
  if(100<=gu16_PressStayCount && 300>gu16_PressStayCount || 500<gu16_PressStayCount)   //100~300 和大于500为Hold住
  {
   gu8_Status = KEY_STATE_HOLD;
  }
  gu8_LEDFlag = 1;
  }

}
/************************  FUNCTION DISCRIPTION  ****************************
        Check key pressed on.
/***************************************************************************/

void ChangeKeyStatus()
{
  
  P1 = 0x0F;
  if(P1 != 0x0F)
  {  
  SetKeyStatusValue();    
  }
 else
 {
  gu16_PressStayCount = 0;
 }
 if(gu8_SecondFlag == 1)
  {
  gu16_SecondCount++;
  }
 if(gu16_SecondCount == 97)
 {
   switch(gu8_SingleClickCount)
   {
    case 2:
     if(Key[0] ==Key[1])
     {
      gu8_CurrentKey = KEY_VALUE_2;
     }
     break;
    case 3:
     if(Key[0] ==Key[1] && Key[1] == Key[2])
     {
      gu8_CurrentKey = KEY_VALUE_3;
     }
     break;
   }
   gu8_SingleClickCount = 0;
   gu16_SecondCount = 0;
   gu8_SecondFlag = 0;
 }
}
/*---------------------------------------------------------------------
                   Test Case(The Interval to check Key Down)
---------------------------------------------------------------------*/
void SetInterVal()
{
 while(1)
 {
   if(gu8_Interval == 1)  //Interval 10ms
   {
   ChangeKeyStatus();
   gu8_Interval  = 0;
   if(gu8_LEDFlag == 1)
   {
    SetLEDValue();
   }
   }
   P0 = gu8_CurrentKey;
  }
}
/************************  FUNCTION DISCRIPTION  ****************************
               Define Timer
/***************************************************************************/
void Timer()
{
 TMOD = 0x01; 
 TH0=HIBYTE; 
 TL0=LIBYTE;
 EA=1;  
 ET0=1;  
 TR0=1; 
 SetInterVal();
}

/*  Interval(10ms):   HIBYTE ((65536-10000)/256)   LIBYTE ((65536-10000)%256)   */
void timer0() interrupt 1
{
 TH0=HIBYTE;
 TL0=LIBYTE;
 gu8_Interval++;
 gu32_GlobalTime++;
}


/*------------------------------------------------
                   Main Menu
------------------------------------------------*/
void main (void)
{
 Timer();
}

 

说明:

   实现单按 长按 Hold不放 1S内双击 三击

0 0