#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内双击 三击