STM32學(xué)習(xí)筆記:單片機(jī)按鍵單擊、雙擊、長按功能實(shí)現(xiàn)
由于項(xiàng)目產(chǎn)品的需要,只能設(shè)置一個(gè)按鍵,但是需要實(shí)現(xiàn)短按(即單擊)切換工作模式、長按開關(guān)機(jī)、雙擊暫停等復(fù)用功能。下圖是三種情況下的按鍵波形。按鍵未按下時(shí)是高電平,按下去是低電平。按鍵單擊時(shí),判斷時(shí)間門檻設(shè)置為50~2000ms;長按門檻為持續(xù)按下2000ms。雙擊可以視為時(shí)間間隔很短的倆次有效單擊,從第一次單擊上升沿到第二次單擊上升沿延時(shí)門檻為100~500ms。
//按鍵按下去會(huì)出現(xiàn)下降沿,設(shè)置按鍵IO口所在的外部端口為下降沿觸發(fā)中斷。voidEXTIX_Init(void){EXTI_InitTypeDefEXTI_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;KEY_Init();//①按鍵端口初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//②開啟AFIO時(shí)鐘//GPIOE.2中斷線以及中斷初始化配置,下降沿觸發(fā)GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//③EXTI_InitStructure.EXTI_Line=EXTI_Line2;EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿觸發(fā)EXTI_InitStructure.EXTI_LineCmd=ENABLE;EXTI_Init(&EXTI_InitStructure);//④初始化中斷線參數(shù)NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;//使能按鍵外部中斷通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;//搶占優(yōu)先級(jí)2,NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;//子優(yōu)先級(jí)2NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能外部中斷通道NVIC_Init(&NVIC_InitStructure);//⑤初始化NVIC}123456789101112131415161718192021中斷服務(wù)函數(shù)
//⑥外部中斷2服務(wù)程序voidEXTI2_IRQHandler(void){if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_2)==0)//按鍵KEY2{key_fall_flag=1;//生成按鍵按下標(biāo)志}EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE2上的中斷標(biāo)志位}1234567891ms定時(shí)器中斷服務(wù)函數(shù)
voidTIM3_IRQHandler(void)//TIM3中斷{if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//檢查TIM3更新中斷發(fā)生與否{if(key_fall_flag==1)//發(fā)生按鍵按下事件{if(GPIO_ReadInputPin(GPIOB,GPIO_PIN_4)==0)//按鍵持續(xù)按下{if(key_holdon_ms<=2000){key_holdon_ms++;}else//按鍵按下到2000ms就判斷長按時(shí)間成立,生成長按標(biāo)志{key_holdon_ms=0;short_key_flag=0;//清短按鍵標(biāo)志key_long_down=1;//長按鍵標(biāo)志置位key_fall_flag=0;//清按鍵按下標(biāo)志}}else//按鍵抬起{if(key_holdon_ms>50)//按下時(shí)間大于50ms,生成單擊標(biāo)志{key_holdon_ms=0;short_key_flag=1;key_long_down=0;key_fall_flag=0;//距離上次單擊時(shí)間在100~500ms之間,則認(rèn)為發(fā)生連擊事件if(keyupCnt>100&&keyupCnt<500){doubleClick=TRUE;short_key_flag=0;}keyUpFlag=TRUE;//單擊抬起按鍵后,生成按鍵抬起標(biāo)志}else//按鍵持續(xù)時(shí)間小于50ms,忽略{key_holdon_ms=0;short_key_flag=0;long_key_flag=0;key_fall_flag=0;}}}if(keyUpFlag)//單擊抬起后,啟動(dòng)計(jì)數(shù),計(jì)數(shù)到500mskeyupCnt++;if(keyupCnt>500){keyupCnt=0;keyUpFlag=FALSE;}}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除TIM3更新中斷標(biāo)志}}