您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 交通运输 > 用状态机做独立按键检测
人机界面最重要的就是按键了,觉得按键做的最好的就是手机的按键了,有长按、敌探、连发等功能。还有组合等。一个好的按键程序用书本上学的按键检测方法已经不能适应工程的需要了,为此人们设计出一种状态机检测按键的方法。在一个系统中按键是随机的,因此系统软件对按键要一直循环查询,由于按键检测过程需要进行消抖处理,因此取状态机的时间序列为10ms,这样不仅可以跳过按键抖动的影响,同时也小于0.3-0.5秒的稳定闭合期,不会将按键的操作过程丢失。程序实现方法,用定时器定时10ms,每隔10ms检测一次按键,将一个按键的检测过程分为几个不同的状态,最简单的分为初使状态-按键闭合确认状态-按键释放状态,如果要求按键实现的功能越多,状态也就越多,比如还有常用的长按状态。以下是一个状态机按键程序,仅供参考。程序基于AVR单片机,key.h文件的一部分#defineKEY0_PORTPORTD#defineKEY0_DDRDDRD#defineKEY0_PINPIND#defineKEY0PD0#defineKEY1_PORTPORTD#defineKEY1_DDRDDRD#defineKEY1_PINPIND#defineKEY1PD1#defineKEY2_PORTPORTD#defineKEY2_DDRDDRD#defineKEY2_PINPIND#defineKEY2PD2#defineKEY3_PORTPORTD#defineKEY3_DDRDDRD#defineKEY3_PINPIND#defineKEY3PD3#defineKEY0_STATUS(BIT_STATUS(KEY0_PIN,KEY0))#defineKEY1_STATUS(BIT_STATUS(KEY1_PIN,KEY1))#defineKEY2_STATUS(BIT_STATUS(KEY2_PIN,KEY2))#defineKEY3_STATUS(BIT_STATUS(KEY3_PIN,KEY3))#defineKEY_SERIES_FLAG200//按键连发开始所需时间长度#defineKEY_SERIES_DELAY5//按键连发的时间间隔长度//按键属性#defineKEY_DOWN0xA0#defineKEY_LONG0xB0#defineKEY_LIAN0xC0#defineKEY_UP0xD0#defineKEY_LONG0xB0#defineKEY_LIAN0xC0#defineKEY_UP0xD0#defineNO_KEY0x00#defineKEY0_DOWN0X01#defineKEY1_DOWN0X02#defineKEY2_DOWN0X03#defineKEY3_DOWN0X04#defineKEY0_PRESS(KEY_DOWN|KEY0_DOWN)#defineKEY1_PRESS(KEY_DOWN|KEY1_DOWN)#defineKEY2_PRESS(KEY_DOWN|KEY2_DOWN)#defineKEY3_PRESS(KEY_DOWN|KEY3_DOWN)key.c文件一部分staticucharGet_Key(void){if(KEY0_STATUS==0)returnKEY0_DOWN;if(KEY1_STATUS==0)returnKEY1_DOWN;if(KEY2_STATUS==0)returnKEY2_DOWN;if(KEY3_STATUS==0)returnKEY3_DOWN;returnNO_KEY;}ucharKey_Scan(void){staticucharKey_State=0;//按键状态staticucharKey_Prev=0;//上一次按键staticucharKey_Delay=0;//按键连发时间staticucharKey_Series=FALSE;//标志连发开始ucharKey_Press=NO_KEY;//按键值ucharKey_Return=NO_KEY;//按键返回值Key_Press=Get_Key();switch(Key_State){case0://按键初始态00if(Key_Press!=NO_KEY)//有按键按下{Key_State=1;//转到按键确认Key_Prev=Key_Press;//保存按键状态}break;case1://按键确认态01if(Key_Press==Key_Prev)//确认和上次按键相同{Key_State=2;//判断按键长按//返回按键按下键值,按键按下就响应,如果想弹起来再响应//可以在弹起来后再返回按键值Key_Return=KEY_DOWN|Key_Prev;}else//按键抬起,是抖动,不响应按键{Key_State=0;}break;case2://按键释放态10if(Key_Press==NO_KEY)//按键释放了{Key_State=0;Key_Delay=0;Key_Series=FALSE;Key_Return=KEY_UP|Key_Prev;//返回按键抬起值break;}if(Key_Press==Key_Prev){Key_Delay++;if((Key_Series==TRUE)&&(Key_DelayKEY_SERIES_DELAY)){Key_Delay=0;Key_Return=KEY_LIAN|Key_Press;//返回连发的值Key_Prev=Key_Press;//记住上次的按键.break;}if(Key_DelayKEY_SERIES_FLAG){Key_Series=TRUE;Key_Delay=0;Key_Return=KEY_LONG|Key_Prev;//返回长按后的值break;}}default:break;}returnKey_Return;}每10ms调用一次按键检测,根据Key_Return的值来判断按键的操作,用状态机省去传统按键的延时去抖,也不在在按键的死等待,对程序时间的利用有很大的帮助,根据按键返回的状态值,事件可以在按键按下响应,也可以在按键弹起来响应,也可以实现连发、长按等功能。
本文标题:用状态机做独立按键检测
链接地址:https://www.777doc.com/doc-5984027 .html