基于江科協非阻塞按鍵教程修改,用于STC單片機環境多按鍵多功能按鍵程序
#ifndef _KEYX3_H_
#define _KEYX3_H_
#define key_count 3
#define key1 0
#define key2 1
#define key3 2
#define hold 0x01//按住不放
#define down 0x02//按下時刻
#define up 0x04//松開時刻
#define single 0x08//單擊
#define ddouble 0x10//雙擊
#define llong 0x20//長按
#define repeat 0x40//重復
void key_tick();//放1ms中斷定時器中
unsigned char key_check(unsigned char n, unsigned char flag);//n按鍵名,flag按鍵動作
#endif
//=======================================================
#include <STC8H.H>
#include "keyx3.h"
#define pressed 1
#define unpressed 0
#define time_double 200
#define time_long 2000
#define time_reper 100
sbit k1 = P3^2;
sbit k2 = P3^3;
sbit k3 = P3^4;
sbit led7 = P2^7;
//7 6 5 4 3 2 1 0
unsigned char key_flag[key_count]; //空 repeat long double single up down hold
// 0x40 0x20 0x10 0x08 0x04 0x02 0x01
//===========================================================
unsigned char key_getstate(unsigned char n)
{
if(n == key1)
{
if(k1 == 0)
{
return pressed;
}
}
else if(n == key2)
{
if(k2 == 0)
{
return pressed;
}
}
else if(n == key3)
{
if(k3 == 0)
{
return pressed;
}
}
return unpressed;
}
//-------------------------------------------------------------------------
unsigned char key_check(unsigned char n, unsigned char flag)//通過對這參數各位檢查,得出結果
{
if(key_flag[n] & flag)
{
if(flag != 0x01)
{
key_flag[n] &= ~flag;
}
return 1;
}
return 0;
}
void key_tick()
{
static unsigned char count, i;
static unsigned char prevstate[key_count], currstate[key_count];
static unsigned char s[key_count];
static unsigned int time[key_count];
for(i = 0; i < key_count; i++)
{
if(time[i] > 0 )
{
time[i]--;
}
}
count++;
if(count >= 20)
{
count = 0;
led7 = ~led7;
for(i = 0; i < key_count; i++)
{
prevstate[i] = currstate[i];
currstate[i] = key_getstate(i);
//--基礎事件---------------------------------------
//--按下與松開,電平觸發-----------------------------
if(prevstate[i] == pressed)
{
//hold = 1
key_flag[i] |= hold;
}
else
{
//hold = 0
key_flag[i] &= ~hold;
}
//--松開后按下,下降沿觸發------------------------------
if(prevstate[i] == unpressed && currstate[i] == pressed)
{
//down = 1
key_flag[i] |= down;
}
//--按下后松開,上升沿觸發------------------------------
if(prevstate[i] == pressed && currstate[i] == unpressed)
{
//up = 1
key_flag[i] |= up;
}
//--高級事件-----------------------------------------------
if(s[i] == 0)//空閑
{
if(currstate[i] == pressed)
{
time[i] = time_long;//設定長按時間
s[i] = 1;
}
}
else if(s[i] == 1)//按鍵已按下
{
if(currstate[i] == unpressed)
{
time[i] = time_double;//設定雙擊時間
s[i] = 2;
}
else if(time[i] == 0)//長按時間到
{
time[i] = time_reper;
//llong = 1
key_flag[i] |= llong;
s[i] = 4;
}
}
else if(s[i] == 2)//按鍵已松開
{
if(currstate[i] == pressed)
{
//double = 1;
key_flag[i] |= ddouble;
s[i] = 3;
}
else if(time[i] == 0)//設定雙擊時間到
{
//single = 1;
key_flag[i] |= single;
s[i] = 0;
}
}
else if(s[i] == 3)//按鍵已雙擊
{
if(currstate[i] == unpressed)
{
s[i] = 0;
}
}
else if(s[i] == 4)//按鍵已長按
{
if(currstate[i] == unpressed)
{
s[i] = 0;
}
else if(time[i] == 0)//重復時間到
{
time[i] = time_reper;
//repeat = 1
key_flag[i] |= repeat;
s[i] = 4;
}
}
}//for大括號
//------------------------------------------
}//20ms大括號
}//函數大括號
|