|
#include<stc15w202s.h>
#include<stdio.h>
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
#define key_no 0
#define key_click 1
#define key_double 2
#define key_long 3
sbit KEY = P3^3;
sbit LED_E1P = P3^1;
sbit LED_G1 = P3^2;
sbit LED2 = P5^5; //W2OUT
sbit LED3 = P5^4;
unsigned char flag;
unsigned char cnt = 0;
static unsigned char key_driver(void)
{
static unsigned char key_state_buffer1 = key_state_0;
static unsigned char key_timer_cnt1 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = KEY; //read the I/O states
switch(key_state_buffer1)
{
case key_state_0:
if(key == 0)
key_state_buffer1 = key_state_1;
//按鍵被按下,狀態(tài)轉(zhuǎn)換到按鍵消抖和確認(rèn)狀態(tài)//
break;
case key_state_1:
if(key == 0)
{
key_timer_cnt1 = 0;
key_state_buffer1 = key_state_2;
//按鍵仍然處于按下狀態(tài)
//消抖完成,key_timer開始準(zhǔn)備計(jì)時(shí)
//狀態(tài)切換到按下時(shí)間計(jì)時(shí)狀態(tài)
}
else
key_state_buffer1 = key_state_0;
//按鍵已經(jīng)抬起,回到按鍵初始狀態(tài)
break; //完成軟件消抖
case key_state_2:
if(key == 1)
{
key_return = key_click; //按鍵抬起,產(chǎn)生一次click操作
key_state_buffer1 = key_state_0; //轉(zhuǎn)換到按鍵初始狀態(tài)
}
else if(++key_timer_cnt1 >= 100) //按鍵繼續(xù)按下,計(jì)時(shí)超過1000ms
{
key_return = key_long; //送回長按事件
key_state_buffer1 = key_state_3; //轉(zhuǎn)換到等待按鍵釋放狀態(tài)
}
break;
case key_state_3: //等待按鍵釋放
if(key == 1) //按鍵釋放
key_state_buffer1 = key_state_0; //切回按鍵初始狀態(tài)
break;
}
return key_return;
}
unsigned char key_read(void)
{
static unsigned char key_state_buffer2 = key_state_0;
static unsigned char key_timer_cnt2 = 0;
unsigned char key_return = key_no;
unsigned char key;
key = key_driver();
switch(key_state_buffer2)
{
case key_state_0:
if(key == key_click)
{
key_timer_cnt2 = 0; //第一次單擊,不返回,到下個(gè)狀態(tài)判斷是否會(huì)出現(xiàn)雙擊
key_state_buffer2 = key_state_1;
}
else
key_return = key; //對(duì)于無鍵、長按,返回原事件
break;
case key_state_1:
if(key == key_click) //又一次單擊,時(shí)間間隔小于500ms
{
key_return = key_double; //返回雙擊事件,回到初始狀態(tài)
key_state_buffer2 = key_state_0;
}
else if(++key_timer_cnt2 >= 50)
{
//這里在下一次的按鍵來臨之前,并且時(shí)間是小于500ms的時(shí)候,就會(huì)一直執(zhí)行的是這個(gè)key_timer_cnt2++.直到下一次的按鍵到來,再判斷看是雙擊還是單擊。
//這里500ms內(nèi)肯定讀到的都是無鍵事件,因?yàn)殚L按大于1000ms
//在1s前底層返回的都是無鍵
key_return = key_click; //500ms內(nèi)沒有再次出現(xiàn)單擊事件,返回單擊事件
key_state_buffer2 = key_state_0; //返回初始狀態(tài)
}
break;
}
return key_return;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TL0 = 0xCD; //設(shè)置定時(shí)初值
TH0 = 0xD4; //設(shè)置定時(shí)初值
TF0 = 0; //清除TF0標(biāo)志
TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
ET0 = 1;
}
void IO_init()
{
P3M0 = 0x01;
P3M1 = 0x01;
P5M0 = 0x00;
P5M1 = 0x00;
}
void main(void)
{
unsigned char key = 1;
Timer0Init();
IO_init();
LED_E1P = 1;
LED_G1 = 1;
LED2 = 1;
LED3 = 0;
EA = 1;
while(1)
{
if(flag)
{
flag=0;
key = key_read();
switch(key)
{
case key_click:LED2 = !LED2; break;
case key_double:LED2 = !LED2;LED3 = !LED3; break;
case key_long: LED2 = 1; LED3 = 1; LED_G1 = 0; LED_E1P = 0; break;
default : break;
}
}
}
}
void Timr0_ISR() interrupt 1
{
cnt++;
if(cnt>=10)
{
cnt = 0;
flag = 1;
}
} |
|