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