/****************************************************************************/ //文 件 名:key.c //功 能:短击\连击 //调用方法:unsigned char keyValue = ReadKey(); //说 明:该程序不适用于阵列键盘. // 该程序不需要使用定时器. // 调用处要加入switch语句来判断相应按键按下并执行相应动作. // 如需要在按键松开后执行动作,则调用函数需要定义一个bit标志位,在default语句里判断标志位状态. // KEY_WOBBLE_TIME 指程序程序执行次数.实际应用中要根据程序的长短来调整成合适的数值. // //备 注:程序思路是当按键被按下时开始计算程序的执行次数,如小于KEY_WOBBLE_TIME,则认为按键没有被按下. // 引用自http://www.rupeng.com/forum/thread-12239-1-1.html,略做更改. // KEIL编译时会提示WARNING C291: not every exit path returns a value.不影响使用. // 如有朋友发现问题所在请联系我. /****************************************************************************/ #include <reg52.h> #define KEY_IO P1 //按键所连的IO口 #define NO_KEY_VALUE 0xf //当按键没有被按下时IO口的值 #define KEY_WOBBLE_TIME 150 //去抖动时间(待定) #define KEY_OVER_TIME 500 //等待进入连击时间(待定),该常数要比正常 //按键时间要长,防止非目的性进入连击模式 #define KEY_QUICK_TIME 200 //等待按键抬起的连击时间(待定) typedef unsigned char uchar; typedef unsigned int uint; uchar ReadKey(){ //判断哪个键被按下 static uchar lastKey = NO_KEY_VALUE ; static uint keyCount = 0; static uint keyOverTime = KEY_OVER_TIME; uchar keyTemp = NO_KEY_VALUE ; keyTemp = KEY_IO & NO_KEY_VALUE ; //读取键值 if(keyTemp == NO_KEY_VALUE ){ //无按键按下时 keyCount = 0; keyOverTime = KEY_OVER_TIME; return NO_KEY_VALUE ; }else{ //有按键按下时 if(keyTemp==lastKey){ if(++keyCount == KEY_WOBBLE_TIME){ //不是第1次按下判断抖动是否结束 return keyTemp; //去抖结束,返回键值 }else{ if(keyCount>keyOverTime){ keyCount = 0; keyOverTime = KEY_QUICK_TIME; } return NO_KEY_VALUE ; } }else{ //是第1次按下则保存键值,下次执行此函数时与读到的键值作比较 lastKey = keyTemp ; //保存第1次读到的键值 keyCount = 0; //延时计数器清零 keyOverTime = KEY_OVER_TIME ; return NO_KEY_VALUE ; } } } /////////////////////////////////////////////////////////////////////////////////// 以上程序例子我用三个按键连在P1^0,P1^1,P1^2,使用中根据实际需要更改 KEY_IO P1 , NO_KEY_VALUE ,KEY_WOBBLE_TIME , KEY_OVER_TIME 500, #define KEY_QUICK_TIME 200 . 如只需要判断单击,把判断连击的代码删除即可. 抛砖引玉^^