四、组合键测试

//浏览器用兼容模式浏览代码

在原来基础上,再增加一个组合功能

定时1MS扫描

键1 :长按开启/关闭,短按切换功能

键2:同时与键1按下1S后,开启其他功能

bit B_1ms=0;
u16 T_2s=0;


#define Const_Key_Jitter  40 //抖动计数
#define Const_Key_Long   1000 //长按1秒

u16 INT1_Cnt;
u16 INT2_Cnt;
bit INT1_Short_Click;
bit INT2_Short_Click;
bit Long_Click;
bit INT1_Lock;
bit INT2_Lock;
bit Power_On;
u8  key_num;
bit INT1_Short_Flag;
bit INT1_Long_Flag;
bit INT2_Short_Flag;
bit INT2_Long_Flag;
#define Const_Flash_5Hz_On     60  // 100ms亮 ,可调整此占空比
#define Const_Flash_5Hz_Off     200-Const_Flash_5Hz_On  // 140ms灭
#define Const_Flash_8Hz_On     40  // 62ms亮
#define Const_Flash_8Hz_Off     125-Const_Flash_8Hz_On  // 65ms灭
#define Flash_Times       5   //闪5次
u8 Temp_On;					 //用于数据交换
u8 Temp_On_Times;	  
u8 Temp_Off;
u8 Temp_Off_Times;
u8 Temp_Times;
bit FLone,FLtwo,Plon;
/*******************************************************
	键1当短按有效时,继续计数,满足长按条件自锁
	短按为松手后判断
	键1长按用于开关机
	键1键2同时按下1S以上,表示组合键	
*******************************************************/
void Key_Scan()
{	 
	if(INT1==1)
	{
		INT1_Cnt=0;	 //按下计数清0
		if(INT1_Lock==1)  //长按锁标志
		{
			INT1_Lock=0;	
		}
		else if (INT1_Short_Click==1)	//短按标志且电源开启
		{
			INT1_Short_Click=0;
			INT1_Short_Flag=1;	  //,短按有效,且松手去判断
			
		}	 	       
		
	}
	else if(INT1_Lock==0) //有键按下,且自锁标志为0,即第一次按下
	{
		INT1_Cnt++;
		if(INT1_Cnt>=Const_Key_Jitter)
		{
			INT1_Short_Click=1;			  //短按有效标志
		
		}
		if(INT1_Cnt>=Const_Key_Long)	  //说明是长按,开自锁
		{
			INT1_Lock=1;			  //长按锁住
			INT1_Short_Click=0;
			INT1_Long_Flag=1;		  //长按有效标志
		
		}
	}
	if(INT2==1)
	{
		INT2_Cnt=0;	 //按下计数清0
		if(INT2_Lock==1)  //长按锁标志
		{
			INT2_Lock=0;	
		}
		else if (INT2_Short_Click==1)	//短按标志且电源开启
		{
			INT2_Short_Click=0;
			INT2_Short_Flag=1;	  //短按有效,且松手去判断
			
		}	 	       
		
	}
	else if(INT2_Lock==0) //有键按下,且自锁标志为0,即第一次按下
	{
		INT2_Cnt++;
		if(INT2_Cnt>=Const_Key_Jitter)
		{
			INT2_Short_Click=1;			  //短按有效标志
		
		}
		if(INT2_Cnt>=Const_Key_Long)	  //说明是长按,开自锁
		{
			INT2_Lock=1;			  //长按锁住
			INT2_Short_Click=0;
			INT2_Long_Flag=1;		  //长按有效标志
		}
	}
}
/*******************************************************
	  判断
	  键1在开机状态下,短按切换功能
	  仅键1长按时,开关机切换
	  仅键2长按时,暂定功能
	  键1键2同时长按时,开启另一功能	
*******************************************************/
void KEY_Result()
{
	if(INT1_Short_Flag&&Power_On)
	{
		INT1_Short_Flag=0;
		key_num++;
		if(key_num>=3)key_num=0;
		switch(key_num)
		{
			case 0:
				Temp_On_Times=Const_Flash_5Hz_On;
				Temp_Off_Times=Const_Flash_5Hz_Off;
				Temp_Times=Flash_Times;
				LED8=0;
				FLone=0;  //开启FLASH
				FLtwo=0;
				break;
			case 1:
				Temp_On_Times=Const_Flash_8Hz_On;
				Temp_Off_Times=Const_Flash_8Hz_Off;
				Temp_Times=Flash_Times;
				break;
			case 2:
				LED8=1;
				FLone=1;   //关闭FLASH
				FLtwo=1;
				RED=0;
				BLUE=0;
				break;
		}
	}
	if(INT1_Long_Flag&&(INT2_Long_Flag))  //同时按下两键
	{
		INT1_Long_Flag=0;
		INT2_Long_Flag=0;
		RED1=~RED1;
	}
	else if(INT1_Long_Flag&&(INT2))	// 按键1满足长按,用按键2在松手状态
	{
		INT1_Long_Flag=0;
		Power_On=~Power_On;		  //长按开关机切换
		if(Power_On==0)			  //长按关机时,直接关闭显示,实用中提醒
		{
			RED=0;
			BLUE=0;
			LED8=0;
		}	
	}
	else if(INT1&&(INT2_Long_Flag))	//按键1在松手状态,按键2满足长按
	{
		INT2_Long_Flag=0;
	}	
		
}
/*******************************************************************
	标志法写闪烁循环
	1、长按开机进入闪烁频率为5Hz:红闪5次,蓝闪5次,红蓝同闪5次
	2、短按改变闪烁频率,即在5Hz、8Hz之间切换
	3、开机状态下: 两标志位:00 表示红频闪,01表示蓝频闪 10表示红频同闪 
	                          11 表示关闭,在照明亮时设置
********************************************************************/
void RED_Flash()
{
	if((Power_On)&&(FLone==0)&&(FLtwo==0))
	{
		if(Plon==0)
		{
			RED=1;
			if((Temp_On--)==0)
			{
				Temp_On=Temp_On_Times;
				Plon=1;
			}
			
		}
		else
		{
			RED=0;
			if((Temp_Off--)==0)
			{
				Temp_Off=Temp_Off_Times;
				Plon=0;
				if((Temp_Times--)==0)
				{
					Temp_Times=Flash_Times;
					FLtwo=1;
				}	
			}
		}
	}
}
void BLUE_Flash()
{
	if((Power_On)&&(FLone==0)&&(FLtwo==1))
	{
		if(Plon==0)
		{
			BLUE=1;
			if((Temp_On--)==0)
			{
				Temp_On=Temp_On_Times;
				Plon=1;
			}
			
		}
		else
		{
			BLUE=0;
			if((Temp_Off--)==0)
			{
				Temp_Off=Temp_Off_Times;
				Plon=0;
				if((Temp_Times--)==0)
				{
					Temp_Times=Flash_Times;

					FLone=1;
					FLtwo=0;
				}	
			}
		}
	}
}
void ALL_Flash()
{
	if((Power_On)&&(FLone==1)&&(FLtwo==0))
	{
		if(Plon==0)
		{
			BLUE=1;
			RED=1;
			if((Temp_On--)==0)
			{
				Temp_On=Temp_On_Times;
				Plon=1;
			}
			
		}
		else
		{
			BLUE=0;
			RED=0;
			if((Temp_Off--)==0)
			{
				Temp_Off=Temp_Off_Times;
				Plon=0;
				if((Temp_Times--)==0)
				{
					Temp_Times=Flash_Times;
					FLone=0;
					FLtwo=0;

				}	
			}
		}
	}
}
void Status_Init()
{
	Temp_On_Times=Const_Flash_5Hz_On;
	Temp_On=Temp_On_Times;
	Temp_Off_Times=Const_Flash_5Hz_Off;
	Temp_Off=Temp_Off_Times;
	Temp_Times=Flash_Times;	
	BLUE=0;
	RED=0;
	LED8=0;
	RED1=0;
	key_num=0;
	FLone=0;
	FLtwo=0;
	INT1_Short_Flag=0;
	INT1_Long_Flag=0;
	INT2_Short_Flag=0;
	INT2_Long_Flag=0;
}
void main( )
{	 

	GPIO_Inilize();
	Timer0_Inilize();
	Exti_Inilize();
	Status_Init();
	delay_ms(5);
	TR0=1;
	EA=1;
	while(1)
	{
		if(B_1ms==1)
		{
			B_1ms=0;
			if(++T_2s>=2000)
			{
				T_2s=0;
				if(INT1&&(Power_On==0)&&INT2)//长按松手后2s,进入睡眠状态
				{
					
					TR0=0;
					Status_Init();
					INT1_Clear();  //清标志 IE1=0	
					INT1_Enable(); //使能按键中断EX1=1,用于唤醒
					INT2_Clear();  //清标志	
					INT2_Enable(); //使能按键中断用于唤醒
					MCU_POWER_DOWN(); //进入睡眠 PCON |= 2
					NOP7();
				}
			}
			Key_Scan();
			RED_Flash();
			BLUE_Flash();
			ALL_Flash();
			KEY_Result();
		}
	
	}
}

/********************* Timer0中断函数************************/
void timer0_int (void) interrupt TIMER0_VECTOR
{
	TF0=0;
	B_1ms=1;
}

void Ext_INT1 (void) interrupt INT1_VECTOR		//进中断时已经清除标志
{
	INT1_Disable();  //关闭按键中断使能 EX1=0
	TR0=1;

}
void Ext_INT2(void) interrupt INT2_VECTOR
{
	INT2_Disable(); 
     TR0=1; //启动后,才能进入睡眠 }

  

 

posted @ 2021-06-21 14:18  来去勿扰  阅读(133)  评论(0)    收藏  举报