0
点赞
收藏
分享

微信扫一扫

按键单击,长按开关机,定时器消抖

鲤鱼打个滚 2022-04-06 阅读 48
c语言

当发生电平变化中断(外部中断)产生一个中断触发标志。然后去定时器中进行处理

目录

按键长按开关机,单击功能切换

单击开关机,功能切换

两个按键控制同一个LED


按键长按开关机,单击功能切换

void isr(void) __interrupt(0)
{
	if(INTFbits.PBIF)					//电平变化中断与睡眠唤醒中断
	{	
		PBIF_Trigger = 1;				//中断触发标志		
		Flag_Time=0;					//消抖清零
		INTFbits.PBIF=0;				//中断标志位清零
	}
	
	if(INTFbits.T0IF)					//1MS定时器
	{
		//Charge_LED++;					//充电时LED进行0.5S翻转
		Flag_Time++;					//消抖累加
		//PWM_M1++;						//模拟PWM
		if(PBIF_Trigger)
		{
			if(Flag_Time>=30)			//30ms消抖
			{
				if(!KEY_DOWN)			//按键触发判断
				{
					Flag_Time=0;		//消抖清零
					Hold_Time++;		//按键按下持续时间
					if(Hold_Time>=60)	//持续时间超过1.8S
					{
						Hold_Time=0;	//清零
						//Long_Press=1;	//长按标志位,在主程序中处理
					}	
				}
				else
				{
					if(Hold_Time)		//保持时间小于1.8S,算为单击
					{
						//PWM_M1=0;		//模拟PWM计数清零
						//Function_M1++;	//功能切换
					}
					/*if(PWM_M1_Function_Nine)	//防止在功能九时,按键无法使功能切换到功能零
					{
						PWM_M1=0;
						Function_M1=0;
						Flag_PWM_M1_ADD=0;
						PWM_M1_Function_Nine=0;
					}*/
					Hold_Time=0;		
					PBIF_Trigger=0;		//中断触发标志清零
				}
			}
		}
		TMR0 = 0XC4;					
		INTFbits.T0IF=0;
	}
}

单击开关机,功能切换

void isr(void) __interrupt(0)
{
    if(INTFbits.PBIF)
    {
    	User_Flag.PBIF_Trigger=1;					//中断触发标志
    	Key_Delay_Time=0;							//消抖清零
        INTFbits.PBIF = 0;							// Clear PBIF(PortB input change interrupt flag bit)
    }
    if(INTFbits.T0IF)								//2ms定时器中断
    {
    	//PWM_Standard++;								//模拟PWM
    	Key_Delay_Time++;							
		if(User_Flag.PBIF_Trigger)
		{
    		if(Key_Delay_Time>12)					//24ms消抖
    		{
	    		if(!KEY_DOWN_Input)					//按键低有效
	    		{
	    			//User_Flag.System_Standby=0;		//退出睡眠模式
	    			//User_Flag.Function_Switch++;	//功能切换
	    			//PWM_Duty_Cycle=0;				//可能可以不写
	    			//PWM_Standard=0;					//基准清零,不写会导致第一个周期偏短
	    			//User_Flag.Variate_ADD=1;		//循环周期增加标志
	    			//User_Flag.Sound_Trigger=1;		//咪头触发标志,切换到模式3时,自动触发一次输出
	    		}
	    		Key_Delay_Time=0;					//消抖清零
	    		User_Flag.PBIF_Trigger=0;			//清除中断触发标志
    		}
    	}
    	TMR0 = 0X81;
        INTFbits.T0IF = 0;							// 清除定时器0中断标志位
    }      
}

两个按键控制同一个LED

KEY_1: 0:空 1:声控模式 2~n:进入睡眠模式 KEY_2: 0:空 1:常亮 2:炫彩呼吸灯 3~n:进入睡眠模式

单击唤醒 单击切换功能

屏蔽一个按键按下不松开,导致当另一个按键按下产生误触发。

void isr(void) __interrupt(0)
{
	if(INTFbits.PABIF)		//电平变化中断与睡眠唤醒中断
    {
    	Key_Delay_Time=0;	//按键消抖时间清零
    	PABIF_Trigger=1;	//中断触发标志 
        INTFbits.PABIF = 0;	// 清除中断标志位
    }
    if(INTFbits.T0IF)		//4ms定时器中断
    {
		if(PABIF_Trigger)	//如果不在中断,可以换成按键输入引脚
		{
			Key_Delay_Time++;	
			if(Key_Delay_Time>5)	//20ms消抖
	    	{
	    		if(!Input_KEY_2)	//KEY_2是否按下 正常模式
	    		{
	    			if((KEY_1_FLAG)&&(KEY_2_FLAG))	//任意一个按键是否按下后未松开
	    			{
		    			//System_Standby=0;			//退出睡眠模式,防止程序未处理完,就进入睡眠模式,使程序卡死                  
						//Function_Switch_1=0;		//声控模式不执行
						//Function_Switch++;			//模式切换 0:空 1:常亮 2:炫彩呼吸灯 3~n:进入睡眠模式
					}
					KEY_2_FLAG=0;					//按键按下标志
	    		}
				else
	    			KEY_2_FLAG=1;	    			//按键松开
    		}
    		if(Key_Delay_Time>5)					//消抖。在我这个编译器中,不能和上面消抖合并。会导致程序出错									{
				if(!Input_KEY_1)					//KEY_1  声控模式
	    		{
	    			if((KEY_1_FLAG)&&(KEY_2_FLAG))	//任意一个按键是否按下后未松开
	    			{
		    			//System_Standby=0;			//退出睡眠模式
		    			//Mic_Trigger=0;				//声音触发标志位清零
						//Function_Switch=0;			//正常模式不执行
						//Function_Switch_1++;		//模式切换 0:空 1:声控模式 2~n:进入睡眠模式
					}
					KEY_1_FLAG=0;					//按键按下
	    		}
	    		else
	    			KEY_1_FLAG=1;					//按键松开
				Key_Delay_Time=0;					//消抖清零
	    		PABIF_Trigger=0;					//清除电平变化触发标志
	    	}
    	}
    	TMR0 = 0X00;
        INTFbits.T0IF = 0;					// Clear PBIF(PortB input change interrupt flag bit)
    }      
}
举报

相关推荐

0 条评论