精华内容
下载资源
问答
  • STM32C8T6按键长按双击。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 有关单片机的 按键 长按 短按 双击 组合按程序分享啊
  • 对back键设置监听器,重写Activity....程序如下: long keydowmtime=0;//按键按下时的时间 long eventtime=0;//事件发生的时间 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TO...

    对back键设置监听器,重写Activity.onKeyDown()方法即可实现功能;程序如下:

    long keydowmtime=0;//按键按下时的时间
    long eventtime=0;//事件发生的时间
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            eventtime=event.getEventTime();
            if(keydowmtime==0){
                keydowmtime=event.getDownTime();
            }else {
                if((eventtime-keydowmtime)<1000){//即两次点击时间小于1s时退出程序,否则,复位
                    MainActivity.this.finish();
                }else{
                    keydowmtime=0;
                }
            }
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                Toast.makeText(MainActivity.this,"再按一次退出", Toast.LENGTH_SHORT).show();
            }
            return super.onKeyDown(keyCode, event);
        }
    }

    转载于:https://www.cnblogs.com/mf0819/p/3840843.html

    展开全文
  • 按键双击,长按有效,单击取消 在学习过程中需要完成稍微复杂一点的功能,按键又不想设计太多(主要节省成本) 在工程中主要有以下几个步骤 一、按键初始化 1、初始化按键IO引脚,这里配置的是上拉输入 2、编写...

    STM32F103按键控制
    按键双击,长按有效,单击取消
    在学习过程中需要完成稍微复杂一点的功能,按键又不想设计太多(主要节省成本)


    在工程中主要有以下几个步骤
    一、按键初始化
    1、初始化按键IO引脚,这里配置的是上拉输入
    2、编写单个按键检测程序(加延时消抖)
    3、宏定义每个按键的状态值Key_State
    4、编写判断是否有按键按下函数,并确定此按键的状态值
    5、编写按键功能函数
    二、定时器初始化
    1、选择通用定时器
    2、配置定时器时间,并开启中断
    3、编写中断服务函数
     

    //宏定义每个按键的状态值Key_State
    #define KEY1_STATE_VALUE	(0x0001)
    #define KEY2_STATE_VALUE	(0x0002)
    #define KEY3_STATE_VALUE	(0x0004)
    #define KEY4_STATE_VALUE	(0x0008)
    
    #define KEY5_STATE_VALUE	(0x0010)
    #define KEY6_STATE_VALUE	(0x0020)
    #define KEY7_STATE_VALUE	(0x0040)
    #define KEY8_STATE_VALUE	(0x0080)
    
    #define KEY9_STATE_VALUE	(0x0100)
    #define KEY10_STATE_VALUE	(0x0200)
    #define KEY11_STATE_VALUE	(0x0400)
    #define KEY12_STATE_VALUE	(0x0800)
    
    //按键延时超时值
    #define Key_Two_Click_Time		200 //200以内双击有效输出
    #define Key_Long_Click_Time		300 //长按300及以上有效输出
    
    
    uint16_t Key_State = 0; 		//按键状态值
    
    uint8_t Key_Value = 0;			//按键按下去的值
    uint8_t Old_Key_Value = 0;		//上一次按键按下去的值
    
    uint8_t Key_Ture_Value = 0;		//最终输出的值
    uint8_t Old_Key_Ture_Value = 0;	//上一次最终输出的值
    
    uint8_t Key_Down_Count_Flag = 0;//按键按下次数的值,用于判断是单击还是双击
    
    uint8_t Key_Down_Flag = 0;		//按键按下标志位,防止一直按着导致按键次数一直增加
    
    uint16_t Key_Click_Time = 0;	//按键次数为1时开始计时,其他状态为0
    
    
    
    void Key_Init(void) //初始化12个按键引脚
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    		
    	GPIO_InitStructure.GPIO_Pin = KYE10_GPIO_PIN|
    								  KYE8_GPIO_PIN|
    								  KYE7_GPIO_PIN|
    								  KYE6_GPIO_PIN|
    								  KYE5_GPIO_PIN|
    								  KYE4_GPIO_PIN|
    								  KYE3_GPIO_PIN|
    								  KYE1_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);	
    	
    	GPIO_InitStructure.GPIO_Pin = KYE2_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB,&GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Pin = KYE9_GPIO_PIN|
    																KYE11_GPIO_PIN|
    																KYE12_GPIO_PIN;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_Init(GPIOC,&GPIO_InitStructure);	
    }
    
    /*
    * 描述:  返回key1控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key1_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    /*
    * 描述:  返回key2控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key2_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    /*
    * 描述:  返回key3控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key3_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    /*
    * 描述:  返回key4控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key4_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    /*
    * 描述:  返回key5控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key5_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    * 描述:  返回key6控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key6_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    * 描述:  返回key7控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key7_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    /*
    * 描述:  返回key8控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key8_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    
    
    /*
    * 描述:  返回key9控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key9_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    * 描述:  返回key10控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key10_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    * 描述:  返回key11控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key11_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    * 描述:  返回key12控制键的状态  
    * 参数:  无
    * 返回值:0按下 1没按下
    */
    uint8_t Get_Key12_State(void)
    {
    	if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
    	{
    		Delay_Ms(10);
    		if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
    		{
    			return 0;
    		}	
    	}
    	return 1;
    }
    /*
    *描述:		判断只有一个按键按下
    *参数:		无
    *返回值:	1:有按键按下,0:无按键按下
    */
    uint8_t Key_Down_Num(void)
    {
    	if(0 == Get_Key1_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key1_State())
    		{
    			Key_State |= KEY1_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY1_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key2_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key2_State())
    		{
    			Key_State |= KEY2_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY2_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key3_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key3_State())
    		{
    			Key_State |= KEY3_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY3_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key4_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key4_State())
    		{
    			Key_State |= KEY4_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY4_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key5_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key5_State())
    		{
    			Key_State |= KEY5_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY5_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key6_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key6_State())
    		{
    			Key_State |= KEY6_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY6_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key7_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key7_State())
    		{
    			Key_State |= KEY7_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY7_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key8_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key8_State())
    		{
    			Key_State |= KEY8_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY8_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key9_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key9_State())
    		{
    			Key_State |= KEY9_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY9_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key10_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key10_State())
    		{
    			Key_State |= KEY10_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY10_STATE_VALUE;
    	}
    
    ///
    	if(0 == Get_Key11_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key11_State())
    		{
    			Key_State |= KEY11_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY11_STATE_VALUE;
    	}	
    	
    ///
    	if(0 == Get_Key12_State())
    	{
    		Delay_Ms(10);
    		if(0 == Get_Key12_State())
    		{
    			Key_State |= KEY12_STATE_VALUE;
    		}
    	}
    	else
    	{
    		Key_State &= ~KEY12_STATE_VALUE;
    	}	
    ///	
    	Key_State &= 0x0fff;
    	if(Key_State != 0)
    	{
    		return 1;
    	}
    	return 0;	
    }
    
    /*
    *描述:		按键检测
    *参数:		无
    *返回值:	无
    */
    void Key_Scanf(void)
    {
    	if(1 == Key_Down_Num())//判断是否有按键按下
    	{
    		Old_Key_Value = Key_Value; //每一次按下记录上一次按键的值
    		switch(Key_State) //判断按键状态值
    		{
    			case KEY1_STATE_VALUE:Key_Value = 1;break;
    			case KEY2_STATE_VALUE:Key_Value = 2;break;
    			case KEY3_STATE_VALUE:Key_Value = 3;break;
    			case KEY4_STATE_VALUE:Key_Value = 4;break;
    			case KEY5_STATE_VALUE:Key_Value = 5;break;
    			case KEY6_STATE_VALUE:Key_Value = 6;break;
    			case KEY7_STATE_VALUE:Key_Value = 7;break;
    			case KEY8_STATE_VALUE:Key_Value = 8;break;						
    			case KEY9_STATE_VALUE:Key_Value = 9;break;		
    			case KEY10_STATE_VALUE:Key_Value = 10;break;
    			case KEY11_STATE_VALUE:Key_Value = 11;break;
    			case KEY12_STATE_VALUE:Key_Value = 12;break;			
    			default:Key_Value = 0;break;			
    		}		
    		if(Key_Down_Flag == 1)
    		{
    			Key_Down_Count_Flag++; //记录按键按下去的次数			
    		}
    		Key_Down_Flag = 0;		
    	}
    	else
    	{
    		Key_Down_Flag = 1;
    	}
    	
    }
    
    /*
    *描述:判断是否是有效键值
    *参数:无
    *返回值:无
    */
    void GetKey_True_Touch(void)
    {
    	if(Key_Down_Count_Flag == 1) //按下1次
    	{
    		if(Key_Down_Flag == 0) //按键按下
    		{
    			//定时器超过长按规定时间
    			if(Key_Click_Time >= Key_Long_Click_Time)
    			{
    				Key_Ture_Value = Key_Value;
    			}
    			else
    			{
    				Key_Ture_Value = 0;
    			}			
    		}
    		else	///按键松开
    		{
    			//判断定时器时间是否超过规定时间
    			//如果超过规定时间,清零变量
    			if(Key_Click_Time > Key_Two_Click_Time)
    			{
    				Key_Ture_Value = 0;				//输出值清零				
    				Key_Click_Time = 0;				//定时器时间清零
    				Key_Down_Count_Flag = 0;	//按键次数清零
    			}
    		}	
    	}
    	else if(Key_Down_Count_Flag == 2)//按下2次
     	{
    		//如果两次按键值相等,说明双击的是同一个按键
    		//如果两次按键值不相等,输出0;
    		if(Old_Key_Value == Key_Value)
    		{
    			Key_Ture_Value = Key_Value;
    		}
    		else
    		{
    			Key_Ture_Value = 0;				//输出值清零	
    		}
    		Key_Click_Time = 0;				//定时器时间清零
    		Key_Down_Count_Flag = 0;	//按键次数清零
    		while(Key_Down_Num());    //等待按键松开
    	}
    	
    }
    
    //定时器配置//
    
    void TIM2_Init(void)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;	
    	NVIC_InitTypeDef 				NVIC_InitStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	
    	//配置周期为5ms
    	TIM_TimeBaseInitStructure.TIM_Period = 4999;
    	TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
    	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
    	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
    	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
    	
    	TIM_ARRPreloadConfig(TIM2,ENABLE);//在ARR上启用或禁用TIMx外设预加载寄存器。
    	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    	TIM_Cmd(TIM2,ENABLE);
    	
    	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
    	
    	NVIC_Init(&NVIC_InitStructure);
    }	
    //中断服务函数
    void TIM2_IRQHandler(void)
    {
    	while(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update))
    	{
    		//按键单击,双击,长按监测
    		if(Key_Down_Count_Flag == 1)
    		{
    			Key_Click_Time++;
    			if(Key_Click_Time > Key_Long_Click_Time)
    			{
    				Key_Click_Time = Key_Long_Click_Time;
    			}			
    		}
    		else
    		{
    				Key_Click_Time = 0;
    		}
    		TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
    	}	
    }

     

    展开全文
  • 第九节:独立按键双击按键触发

    千次阅读 2017-01-03 06:21:46
    这一节教大家如何实现按键双击触发的功能,这种功能类似鼠标的双击。要教会大家一个知识点:如何在上一节的基础上,略作修改,就可以实现按键的双击功能。 具体内容,请看源代码讲解。 (1)硬件平台:基于朱...
    第九节:独立按键的双击按键触发。

    开场白:
    上一节讲了在定时中断函数里处理独立按键的扫描程序,这种结构的程序我用在了很多项目上。这一节教大家如何实现按键双击触发的功能,这种功能类似鼠标的双击。要教会大家一个知识点:如何在上一节的基础上,略作修改,就可以实现按键的双击功能。

    具体内容,请看源代码讲解。

    (1)硬件平台:基于朱兆祺51单片机学习板。用矩阵键盘中的S1和S5号键作为独立按键,记得把输出线P0.4一直输出低电平,模拟独立按键的触发地GND。

    (2)实现功能:有两个独立按键,每双击一个独立按键,蜂鸣器发出“滴”的一声后就停。

    (3)源代码讲解如下:
    #include "REG52.H"

    #define const_voice_short  40   //蜂鸣器短叫的持续时间


    /* 注释一:
    * 调整抖动时间阀值的大小,可以更改按键的触发灵敏度。
    * 去抖动的时间本质上等于累计定时中断次数的时间。
    */
    #define const_key_time1  20    //按键去抖动延时的时间
    #define const_key_time2  20    //按键去抖动延时的时间

    /* 注释二:
    * 有效时间差,是指连续两次按键触发的最大有效间隔时间。
    * 如果双击的两个按键按下的时间间隔太长,则视为无效双击。
    */
    #define const_interval_time1  200     //连续两次按键之间的有效时间差
    #define const_interval_time2  200     //连续两次按键之间的有效时间差

    void initial_myself();    
    void initial_peripheral();
    void delay_long(unsigned int uiDelaylong);
    void T0_time();  //定时中断函数
    void key_service(); //按键服务的应用程序
    void key_scan(); //按键扫描函数 放在定时中断里

    sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
    sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
    sbit key_gnd_dr=P0^4; //模拟独立按键的地GND,因此必须一直输出低电平

    sbit beep_dr=P2^7; //蜂鸣器的驱动IO口

    unsigned char ucKeySec=0;   //被触发的按键编号

    unsigned int  uiKeyTimeCnt1=0; //按键去抖动延时计数器
    unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
    unsigned char ucKeyTouchCnt1=0; //按键按下的次数记录
    unsigned int  uiKeyIntervalCnt1=0; //按键间隔的时间计数器

    unsigned int  uiKeyTimeCnt2=0; //按键去抖动延时计数器
    unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
    unsigned char ucKeyTouchCnt2=0; //按键按下的次数记录
    unsigned int  uiKeyIntervalCnt2=0; //按键间隔的时间计数器

    unsigned int  uiVoiceCnt=0;  //蜂鸣器鸣叫的持续时间计数器

    void main() 
      {
       initial_myself();  
       delay_long(100);   
       initial_peripheral(); 
       while(1)  
       { 
           key_service(); //按键服务的应用程序
       }

    }

    void key_scan()//按键扫描函数 放在定时中断里
    {  
    /* 注释三:
    * 独立双击按键扫描的详细过程:
    * 第一步:平时没有按键被触发时,按键的自锁标志,去抖动延时计数器一直被清零。
    *         如果之前已经有按键触发过一次,那么启动时间间隔计数器uiKeyIntervalCnt1,
    *         在这个允许的时间差范围内,如果一直没有第二次按键触发,则把累加按键触发的
    *         次数ucKeyTouchCnt1也清零。
    * 第二步:一旦有按键被按下,去抖动延时计数器开始在定时中断函数里累加,在还没累加到
    *         阀值const_key_time1时,如果在这期间由于受外界干扰或者按键抖动,而使
    *         IO口突然瞬间触发成高电平,这个时候马上把延时计数器uiKeyTimeCnt1
    *         清零了,这个过程非常巧妙,非常有效地去除瞬间的杂波干扰。这是我实战中摸索出来的。
    *         以后凡是用到开关感应器的时候,都可以用类似这样的方法去干扰。
    * 第三步:如果按键按下的时间超过了阀值const_key_time1,马上把自锁标志ucKeyLock1置位,
    *         防止按住按键不松手后一直触发。与此同时,累加一次按键次数,如果按键次数累加有两次以上,
    *         则认为触发双击按键,并把编号ucKeySec赋值。 
    * 第四步:等按键松开后,自锁标志ucKeyLock1及时清零,为下一次自锁做准备。并且累加间隔时间,
    *         防止两次按键的间隔时间太长。
    * 第五步:以上整个过程,就是识别按键IO口下降沿触发的过程。
    */
      if(key_sr1==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
      {
             ucKeyLock1=0; //按键自锁标志清零
             uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。      
                     if(ucKeyTouchCnt1>0) //之前已经有按键触发过一次,再来一次就构成双击
                     {
                         uiKeyIntervalCnt1++; //按键间隔的时间计数器累加
                             if(uiKeyIntervalCnt1>const_interval_time1) //超过最大允许的间隔时间
                             {
                                uiKeyIntervalCnt1=0; //时间计数器清零
                                ucKeyTouchCnt1=0; //清零按键的按下的次数
                             }
                     }
      }
      else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
      {
         uiKeyTimeCnt1++; //累加定时中断次数
         if(uiKeyTimeCnt1>const_key_time1)
         {
            uiKeyTimeCnt1=0; 
            ucKeyLock1=1;  //自锁按键置位,避免一直触发
                    uiKeyIntervalCnt1=0; //按键有效间隔的时间计数器清零

                    ucKeyTouchCnt1++;
                    if(ucKeyTouchCnt1>1)  //连续被按了两次以上
                    {
                        ucKeyTouchCnt1=0;  //统计按键次数清零
                        ucKeySec=1;    //触发1号键
                    }

         }
      }




      if(key_sr2==1)
      {
             ucKeyLock2=0; 
             uiKeyTimeCnt2=0;
                      if(ucKeyTouchCnt2>0)
                     {
                         uiKeyIntervalCnt2++; //按键间隔的时间计数器累加
                             if(uiKeyIntervalCnt2>const_interval_time2) //超过最大允许的间隔时间
                             {
                                uiKeyIntervalCnt2=0; //时间计数器清零
                                ucKeyTouchCnt2=0; //清零按键的按下的次数
                             }
                     }
      }
      else if(ucKeyLock2==0)
      {
         uiKeyTimeCnt2++; //累加定时中断次数
         if(uiKeyTimeCnt2>const_key_time2)
         {
            uiKeyTimeCnt2=0;
            ucKeyLock2=1; 
                    uiKeyIntervalCnt2=0; //按键有效间隔的时间计数器清零

                    ucKeyTouchCnt2++;
                    if(ucKeyTouchCnt2>1)  //连续被按了两次以上
                    {
                        ucKeyTouchCnt2=0;  //统计按键次数清零
                        ucKeySec=2;    //触发2号键
                    }
         }
      }

    }


    void key_service() //第三区 按键服务的应用程序
    {
      switch(ucKeySec) //按键服务状态切换
      {
        case 1:// 1号键 双击  对应朱兆祺学习板的S1键

                  uiVoiceCnt=const_voice_short; //按键声音触发,滴一声就停。
                  ucKeySec=0;  //响应按键服务处理程序后,按键编号清零,避免一致触发
              break;        
        case 2:// 2号键 双击  对应朱兆祺学习板的S5键

                  uiVoiceCnt=const_voice_short; //按键声音触发,滴一声就停。
                  ucKeySec=0;  //响应按键服务处理程序后,按键编号清零,避免一致触发
              break;                    
      }                
    }



    void T0_time() interrupt 1
    {
      TF0=0;  //清除中断标志
      TR0=0; //关中断

      key_scan(); //按键扫描函数

      if(uiVoiceCnt!=0)
      {
         uiVoiceCnt--; //每次进入定时中断都自减1,直到等于零为止。才停止鸣叫
             beep_dr=0;  //蜂鸣器是PNP三极管控制,低电平就开始鸣叫。
      }
      else
      {
         ; //此处多加一个空指令,想维持跟if括号语句的数量对称,都是两条指令。不加也可以。
               beep_dr=1;  //蜂鸣器是PNP三极管控制,高电平就停止鸣叫。
      }


      TH0=0xf8;   //重装初始值(65535-2000)=63535=0xf82f
      TL0=0x2f;
      TR0=1;  //开中断
    }


    void delay_long(unsigned int uiDelayLong)
    {
       unsigned int i;
       unsigned int j;
       for(i=0;i<uiDelayLong;i++)
       {
          for(j=0;j<500;j++)  //内嵌循环的空指令数量
              {
                 ; //一个分号相当于执行一条空语句
              }
       }
    }


    void initial_myself()  //第一区 初始化单片机
    {
    /* 注释四:
    * 矩阵键盘也可以做独立按键,前提是把某一根公共输出线输出低电平,
    * 模拟独立按键的触发地,本程序中,把key_gnd_dr输出低电平。
    * 朱兆祺51学习板的S1和S5两个按键就是本程序中用到的两个独立按键。
    */
      key_gnd_dr=0; //模拟独立按键的地GND,因此必须一直输出低电平


      beep_dr=1; //用PNP三极管控制蜂鸣器,输出高电平时不叫。


      TMOD=0x01;  //设置定时器0为工作方式1


      TH0=0xf8;   //重装初始值(65535-2000)=63535=0xf82f
      TL0=0x2f;

    }
    void initial_peripheral() //第二区 初始化外围
    {
      EA=1;     //开总中断
      ET0=1;    //允许定时中断
      TR0=1;    //启动定时中断

    }

    总结陈词:
    假如要两个独立按键实现组合按键的功能,我们该怎么写程序?欲知详情,请听下回分解-----独立按键的组合按键触发
    展开全文
  • 思路同按键长按,在key_state_2里判断如何没有松开的时候加一,如果我设置一个标志让按键按下一次后标志位置1,这样我就能统计按下了几次,这样就可以实现双击和三击的功能,程序如下,key_press=0x77是长按部分,...

    思路同按键长按,在key_state_2里判断如何没有松开的时候加一,如果我设置一个标志让按键按下一次后标志位置1,这样我就能统计按下了几次,这样就可以实现双击和三击的功能,程序如下,key_press=0x77是长按部分,key_press=0xee是双击部分

    case KEY_STATE_2:
    if(key_press == NO_KEY)
    {
    	key_state=KEY_STATE_0;
    }
    else
    {
    	if(key_press==0x77)
    	{
    		sustain_press_time++;
    		if(sustain_press_time==400)
    		{
    			sustain_press_time=0;
    			led_flag=1;
    		}	
    	}
    	if(key_press==0xee)
    	{
    		if(key19_one_flag==1)
    		{
    			key19_one_flag=0;
    			sustain_press_time_ee++;
    			if(sustain_press_time_ee==2)
    			{
    				sustain_press_time_ee=0;
    				led2_flag=1;
    			}
    		}
    	}
    }
    break;
    
    
    展开全文
  • 按键程序

    2021-02-20 09:44:25
    自己写的按键持续,支持短按、长按、双击、连发 链接:https://pan.baidu.com/s/1lGyoOAK8Aib6Z3zrjIlWOA 提取码:2sb4
  • 引言:在很多项目开发过程中我们通常会涉及到按键的使用,为了使按键的功能更多远化我们通常会区别按键的单击、双击、长按等操作过程从而实现更多的功能。现在让我们来分析一下他们的实现原理和过程。 一、原理解析...
  • STM32CUEB关于KEIL5、stm32f103c8t6的单次、双击、长按三种按键程序代码实现 .
  • 概括比较完全 包括了单片机 按键 长按 短按 双击 组合按等功能
  • 一个按键扫描的程序很经典,有单击 双击 还有长按 都可以自己设置时间参数,而且双击的时候不会出发单击,里面的算法思想很经典,我经常使用可以拿来学习一下··
  • 按键】[独立按键] - 2:双击

    千次阅读 2016-03-29 10:28:55
    1)在预设的时间间隔内完成第二次【单击】,按键释放后,响应返回有效键值【双击】。 2)如果第二次按下键并一直按住,当按住的时间超过设定的时间间隔(300ms)后,会响应第一个【单击】,并返回有效键值【单击】...
  • 一、使用proteus绘制...二、编写程序 /******************************************************************************************************************** ---- @Project: Independent-KEY ---- @File: ...
  • 下面这段是引言,和按键程序实质内容没有任何关系,可以当P话,可直接跳到分割线之后的正文部分。...但是在其上面扩展双击和三击以及多击程序时,遇到了麻烦(其实就是不会啦),于是在网上看了某个老师的经
  • 基于51单片机的独立按键单击、双击,长按,多次按的项目工程一、前言1、基于51单片机的独立按键单击、双击,长按,多次按的项目工程包括用Keil软件编写单片机C语言程序和用Proteus软件仿真单片机外围电路2、基于51...
  • 目录- 单击、双击、长按原理解析 - 程序源码 - 思考总结引言:在很多项目开发过程中我们通常会涉及到按键的使用,为了使按键的功能更多远化我们通常会区别按键的单击、双击、长按等操作过程从而实现更多的功能。...
  • 触摸按键的长按以及单击、双击、三击、四击程序 长按的本质是限定一段时间内电平均保持低电平有效,而双、三、四击都是根据递推关系,即双击是在单击的基础上进一步判断,以此类推,写程序时,只需要加一个标志变量...
  • 目录: 1:概述 2:stm32外部中断配置 3:code 概述: 1:本篇利用按键中断输入方式,当按键触发,中断处理函数置按键扫描标志位为1,...当K1按键双击,LED3闪烁; 3:优点:相比于轮询扫描按键键值的方式,按键响
  • 目录STM32-蓝桥杯嵌入式之三行按键检测一、检测按键下降沿分析二、检测按键上升沿分析三、按键检测程序的核心代码 首先先说说异或,异或即相同为0不同为1,可以通过使用异或来判断某一状态发生改变,思路:如果当前...
  • 按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击]。本文分为三个部分, 第一个部分是说[单击],[长按]的程序; 第二部分是讲[双击]; 第三部分是讲[三击],[N击]; 一、 ...
  • 概述: 1:本篇利用按键中断输入方式,当按键触发,中断处理函数置按键...当K1按键双击,LED3闪烁; 3:优点:相比于轮询扫描按键键值的方式,按键响应速度更快,节约CPU资源; 4:参考资料:stm32中文参考手册(EXI
  • Android 双击返回键退出程序的方法总结 下面先说说LZ思路,具体如下: 1. 第一种就是根据用户点击俩次的时间间隔去判断是否退出程序; 2. 第二种就是使用Android中计时器(Timer),其实这俩种都差不多. 思路是有...
  • // 作为标识符 private static boolean flag = false;... // 重写按键事件 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { exi
  •  双击返回键退出程序,一般有两种实现思路,一种是用一个布尔值变量来记录按键事件,并通过线程延时来实现效果;另外一种是直接通过记录按键时间计算时间差实现功能,现在就跟大家分享下代码吧、O(∩_∩)O哈哈~ 1...
  •  双击返回键退出程序,一般有两种实现思路,一种是用一个布尔值变量来记录按键事件,并通过线程延时来实现效果;另外一种是直接通过记录按键时间计算时间差实现功能,现在就跟大家分享下代码吧、O(∩_∩)...
  • 在开发应用程序的时候,有一种功能是非常常用到的,那就是迅速双击返回按钮,然后实现退出Activity的功能。本人在网上看了很多资料代码,总结起来,主要有两种比较好的方式。一种是开线程延时执行,一种是记录按键...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 366
精华内容 146
关键字:

按键双击程序