二、獨立按鍵開關機,紅藍閃爍燈切換頻率實驗
阿新 • • 發佈:2021-06-18
功能:單鍵操作 長按開關機;開機狀態下,短按切換閃爍頻率5Hz 8Hz,紅藍燈雙閃
閃爍方式:紅單閃5次----藍單閃5次----紅藍同閃5次
1MS掃描
bit B_1ms=0; u16 T_2s=0; #define Const_Key_Jitter 40 //抖動計數 #define Const_Key_Long 1000 //長按1秒 u16 INT1_Cnt=0; bit Short_Click=0; bit Long_Click=0; bit INT1_Lock=0; bit Power_On=0; u8 key_num=0; bit key_Flag=0; #define Const_Flash_5Hz_On 100 // 100ms #define Const_Flash_5Hz_Off 100 // 100ms #define Const_Flash_8Hz_On 62 // 62ms #define Const_Flash_8Hz_Off 63 // 63ms #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; /******************************************************* 當短按有效時,繼續計數,滿足長按條件自鎖 鬆手解鎖 短按為鬆手後判斷 長按不需要鬆手就有效 *******************************************************/ void Key_Scan() { if(INT1==1) { INT1_Cnt=0; //按下計數清0 if(INT1_Lock==1) //長按鎖標誌 { INT1_Lock=0; } else if (Short_Click==1&&(Power_On==1)) //短按標誌且電源開啟 { Short_Click=0; key_Flag=1; } } else if(INT1_Lock==0) //有鍵按下,且自鎖標誌為0,即第一次按下 { INT1_Cnt++; if(INT1_Cnt>=Const_Key_Jitter) { Short_Click=1; //短按有效標誌 } if(INT1_Cnt>=Const_Key_Long) //說明是長按,開自鎖 { INT1_Lock=1; //長按鎖住 Short_Click=0; Power_On=~Power_On; //長按開關機 } } } /******************************************************* 當短按有效時,根據鍵值,切換頻率 *******************************************************/ void KEY_Result() { if(key_Flag) { key_Flag=0; key_num++; if(key_num>=2)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; break; case 1: Temp_On_Times=Const_Flash_8Hz_On; Temp_Off_Times=Const_Flash_8Hz_Off; Temp_Times=Flash_Times; break; } } } /******************************************************************* 標誌法寫閃爍迴圈 1、長按開機進入閃爍頻率為5Hz:紅閃5次,藍閃5次,紅藍同閃5次 2、短按改變閃爍頻率,即在5Hz、8Hz之間切換 3、長按關機,並進入睡眠狀態 ********************************************************************/ 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; FLone=1; } } } } } void BLUE_Flash() { if((Power_On)&&(FLone==1)&&(FLtwo==0)) { 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; FLtwo=1; } } } } } void ALL_Flash() { if((Power_On)&&(FLtwo==1)) { 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 main( ) { GPIO_Inilize(); Timer0_Inilize(); Exti_Inilize(); 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; 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)) { TR0=0; BLUE=0; RED=0; INT1_Clear(); //清標誌 IE1=0 INT1_Enable(); //使能按鍵中斷EX1=1,用於喚醒 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; }