四、组合键测试
//浏览器用兼容模式浏览代码
在原来基础上,再增加一个组合功能
定时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; //启动后,才能进入睡眠
}
浙公网安备 33010602011771号