由于项目产品的需要,只能设置一个按键,但是需要实现短按(即单击)切换工作模式、长按开关机、双击暂停等复用功能。下图是三种情况下的按键波形。按键未按下时是高电平,按下去是低电平。按键单击时,判断时间门槛设置为50~2000ms;长按门槛为持续按下2000ms。双击可以视为时间间隔很短的俩次有效单击,从第一次单击上升沿到第二次单击上升沿延时门槛为100~500ms。
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
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;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
中断服务函数
void EXTI2_IRQHandler(void)
{
if(GPIO_ReadInputPin(GPIOE,GPIO_PIN_2)==0)
{
key_fall_flag = 1;
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
1ms定时器中断服务函数
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
if(key_fall_flag==1)
{
if(GPIO_ReadInputPin(GPIOB,GPIO_PIN_4)==0)
{
if(key_holdon_ms <= 2000)
{
key_holdon_ms++;
}
else
{
key_holdon_ms = 0;
short_key_flag=0;
key_long_down = 1;
key_fall_flag = 0;
}
}
else
{
if(key_holdon_ms>50)
{
key_holdon_ms=0;
short_key_flag=1;
key_long_down =0;
key_fall_flag=0;
if(keyupCnt>100 && keyupCnt<500)
{
doubleClick = TRUE;
short_key_flag=0;
}
keyUpFlag = TRUE;
}
else
{
key_holdon_ms=0;
short_key_flag=0;
long_key_flag=0;
key_fall_flag=0;
}
}
}
if(keyUpFlag)
keyupCnt++;
if(keyupCnt>500)
{
keyupCnt = 0;
keyUpFlag = FALSE;
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
}
}