本帖最后由 chuangong 于 2009-8-31 22:50 编辑
介绍我的一个按键小程序,杜绝delay()去抖 keyScan。希望对初学者有些启发。主程序中每约20ms执行一次keycol(),无需delay去抖。
不吝指正,高手勿笑,。
typedef struct
{
uchar Key_T20ms;
union
{
uchar Key_Flag ;
struct
{
unsigned keyflagdw : 1 ; //有按键按下
unsigned keyflaged : 1 ; //按键有效
unsigned keyenpres : 1 ; ////轻按按键方式,松键有效标志
unsigned keyflag1S : 1 ;
unsigned keyflagOver1S : 1 ;
}_Key_Flag;
}_KEY_FLAG;
}_KEY_COL ;
#define keydownF _KEY_FLAG._Key_Flag.keyflagdw
#define keyEndownF _KEY_FLAG._Key_Flag.keyflaged
#define keypress _KEY_FLAG._Key_Flag.keyenpres
#define keydown1S _KEY_FLAG._Key_Flag.keyflag1S
#define keydownOver1S _KEY_FLAG._Key_Flag.keyflagOver1S
_KEY_COL Key_add,Key_sub;
void main(void)
{
while(1)
{
//想下办法每约20ms执行一次keycol();就OK。
}
}
void keycol(void)
{
keycheck();
keymark(&Key_add);
keymark(&Key_sub);
if(Key_add.keyEndownF == 1 ) //轻按键有效
{
Key_add.keyEndownF = 0 ;
}
if(Key_add.keydown1S == 1 )//长按键有效
{
Key_add.keydown1S = 0 ;
/*做你要的动作*/
}
if(Key_sub.keyEndownF == 1 )
{
Key_sub.keyEndownF = 0 ;
/*做你要的动作*/
}
if(Key_sub.keydown1S == 1 )
{
Key_sub.keydown1S = 0 ;
/*做你要的动作*/
}
}
void keycheck(void)
{
if(KeyAdd) //如果KeyAdd建按下
{
Key_add.keydownF = 1;
}
else
{
Key_add.keydownF = 0;
}
if(KeySub)//如果KeySub建按下
{
Key_sub.keydownF = 1;
}
else
{
Key_sub.keydownF = 0;
}
}
}
void keymark(_KEY_COL *keyflag)
{
if((keyflag->keydownF) == 1)//有按键按下
{
// KeyUp_count = 0 ;
keyflag->Key_T20ms ++ ;
//keyflag->keypress = 0 ;
if(keyflag->Key_T20ms==3) // >60ms去抖
{
keyflag->keyEndownF = 1 ; //按键有效
//Sys_Keydown = 1 ; //系统按键标志
//KeyUp_cnl = 0 ; //
}
if(keyflag->Key_T20ms>=50) //长按键20*50=1S 加1,如果按键不放开,每(50-30)*20=400mS加输出一次动作
{
keyflag->Key_T20ms = 30 ;
keyflag->keydown1S = 1 ;
keyflag->keydownOver1S = 1 ;
}
}
else
{
/*if(keyflag->keyEndownF == 1 ) //轻按按键方式,松键才判动作有效
{
keyflag->keyEndownF = 0 ; //
if(keyflag->keydownOver1S == 0)
keyflag->keypress = 1 ;
}*/
keyflag->Key_T20ms = 0 ;
keyflag->keydownOver1S = 0 ;
//KeyUp_cnl++;
/*if(KeyUp_cnl>=100) //2s
{
Sys_Keydown = 0 ;
}*/
}
} |