stm32外部中断按钮短按长按1.0

 key.c

 
#define PwmAddKey_0   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) //读取按键PwmAddKey_0 (B8)
#define PwmReduceKey_0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)//读取按PwmReduceKey_0(B9)
#define LeftKey_0   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)  //读取按键LeftKEY_0  (B12)
#define RightKey_0 	GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)//读取按键RightKEY_0	  (B13)
#define RightOpenTimeReduceKey_0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)//读取按键RightOpenTimeReduceKey_0  (B14)


#define LeftKey_Pres	 						1	
#define RightKey_Pres							2		
#define RightOpenTimeReduceKey_Pres	            3	
#define PwmAddKey_Pres	 						4			
#define PwmReduceKey_Pres						5




void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//使能AFIO时钟
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);	
}
	
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//返回值:
//0,没有任何按键按下
unsigned char KEY_Scan(unsigned char mode)
{	 
	static unsigned char key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	if(key_up&&(PwmAddKey_0==0||PwmReduceKey_0==0||LeftKey_0==0||RightKey_0==0||RightOpenTimeReduceKey_0==0))
	{
		Delayms(5);//去抖动 
		key_up=0;
		
		if(PwmAddKey_0==0)
			return PwmAddKey_Pres;
		else if(PwmReduceKey_0==0)
			return PwmReduceKey_Pres;
		else if(LeftKey_0==0)						
			return LeftKey_Pres;
		else if(RightKey_0==0)
			return RightKey_Pres;
		else if(RightOpenTimeReduceKey_0==0)
			return RightOpenTimeReduceKey_Pres; 
	
	}	
	else if(PwmAddKey_0==1||PwmReduceKey_0==1||LeftKey_0==1||RightKey_0==1||RightOpenTimeReduceKey_0==1)key_up=1; 	     
	return 0;// 无按键按下
	
}

 exti.c



/**************打开复用时钟PB7,PB8,PB9****************/
void EXTI_GPIO_Init9_5(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;   //外部中断初始化
	//GPIO_InitTypeDef GPIO_InitStructure; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//使能AFIO时钟
	
	/*GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);*/
	
/******************配置EXTI_Line8**********************************/
	EXTI_ClearITPendingBit(EXTI_Line8);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);//PB3
	EXTI_InitStructure.EXTI_Line=EXTI_Line8; 				//PB3,对应:EXTI_Line3
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   		//中断事件
	EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;   	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;  				//中断线使能
	EXTI_Init(&EXTI_InitStructure);     						//配置
/******************配置EXTI_Line9**********************************/
	EXTI_ClearITPendingBit(EXTI_Line9);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);//PB9
	EXTI_InitStructure.EXTI_Line=EXTI_Line9; 					//PB9,对应:EXTI_Line9
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   		//中断事件
	EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;   	//下降沿触发
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;  					//中断线使能
	EXTI_Init(&EXTI_InitStructure);     						//配置
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);   				//NVIC2
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;   			//外部中断2
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; 	//抢先优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;   				//子优先级2    
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;     				//使能
	NVIC_Init(&NVIC_InitStructure);	   							//配置
}

 外部中断函数






#define PwmAddKey_EXTI		EXTI_Line8	//B8			增加PWM占空比
#define PwmReduceKey_EXTI	EXTI_Line9	//B9			减少PWM占空比
unsigned int PWMLeft=50;	      //PWMLaft的占空比
unsigned int MyKeyTime=0;	      //按键按下的的时间标志


/**********************外部中断EXTI9_5****************************/
void EXTI9_5_IRQHandler(void)										
{				
    if(EXTI_GetITStatus(PwmAddKey_EXTI)!= RESET)	//判断是否按下了PwmAddKey按钮
    {
		Delayms(3); 							//按键消抖
		while(PwmAddKey_0==0)			//再次确认
		{
			if(PwmAddKey_0==0)		//按钮短按状态
			{
				PWMLeft+=1;					//PWM值增加
				if(PWMLeft>=100)PWMLeft=100;//当PWM值大于等于100时就为100
				MyKeyTime++;	//按下的时间标志位
				Delayms(500);	//PWM每隔50ms加1
				if(MyKeyTime==4)//如果按键按下超过2秒=500ms*4
				{
					while(PwmAddKey_0==0)//进入长按状态
					{
						PWMLeft+=1;	//PWM值增加
						if(PWMLeft>=100)PWMLeft=100;//当PWM值大于等于于100时就为100
						Delayms(50);//PWM每隔50ms加1
					}
					MyKeyTime=0;	//清除标志位
					
				}
                while(PwmAddKey_EXTI==0);	//松手检测
			}	
		}
		EXTI_ClearITPendingBit(PwmAddKey_EXTI);		//清除标志位
   }
	 if(EXTI_GetITStatus(PwmReduceKey_EXTI)!= RESET)	//判断是否按下了PwmReduceKey按钮
   {
		Delayms(3); 									//按键消抖
		while(PwmReduceKey_0==0)			//再次确认
		{
    		if(PwmReduceKey_0==0)	//按钮短按状态
			{
				PWMLeft-=1;	//PWM值减小
				if((PWMLeft<=0)||(PWMLeft>=100))PWMLeft=0;//当PWM值小于0时就为0
				MyKeyTime++;	//按键按下时间标志位
				Delayms(500);	//PWM每隔50ms加1
				if(MyKeyTime==4)	//如果按键按下超过2秒=500ms*4
				{
					while(PwmReduceKey_0==0)//进入长按状态
					{
						PWMLeft-=1;									//PWM值减小
						if((PWMLeft<=0)||(PWMLeft>=100))PWMLeft=0;//当PWM值小于0时就为0
						Delayms(50);			//PWM每隔50ms加1
					}
					MyKeyTime=0;		//清除标志位
					
				}
                while(PwmReduceKey_EXTI==0);	//松手检测
			}	
		}
		EXTI_ClearITPendingBit(PwmReduceKey_EXTI);		//清除标志位
   }
}

 

你可能感兴趣的:(STM32)