STM32F103按键控制,按键双击,长按有效,单击取消

STM32F103按键控制
按键双击,长按有效,单击取消
在学习过程中需要完成稍微复杂一点的功能,按键又不想设计太多(主要节省成本)


在工程中主要有以下几个步骤
一、按键初始化
1、初始化按键IO引脚,这里配置的是上拉输入
2、编写单个按键检测程序(加延时消抖)
3、宏定义每个按键的状态值Key_State
4、编写判断是否有按键按下函数,并确定此按键的状态值
5、编写按键功能函数
二、定时器初始化
1、选择通用定时器
2、配置定时器时间,并开启中断
3、编写中断服务函数
 

//宏定义每个按键的状态值Key_State
#define KEY1_STATE_VALUE	(0x0001)
#define KEY2_STATE_VALUE	(0x0002)
#define KEY3_STATE_VALUE	(0x0004)
#define KEY4_STATE_VALUE	(0x0008)

#define KEY5_STATE_VALUE	(0x0010)
#define KEY6_STATE_VALUE	(0x0020)
#define KEY7_STATE_VALUE	(0x0040)
#define KEY8_STATE_VALUE	(0x0080)

#define KEY9_STATE_VALUE	(0x0100)
#define KEY10_STATE_VALUE	(0x0200)
#define KEY11_STATE_VALUE	(0x0400)
#define KEY12_STATE_VALUE	(0x0800)

//按键延时超时值
#define Key_Two_Click_Time		200 //200以内双击有效输出
#define Key_Long_Click_Time		300 //长按300及以上有效输出


uint16_t Key_State = 0; 		//按键状态值

uint8_t Key_Value = 0;			//按键按下去的值
uint8_t Old_Key_Value = 0;		//上一次按键按下去的值

uint8_t Key_Ture_Value = 0;		//最终输出的值
uint8_t Old_Key_Ture_Value = 0;	//上一次最终输出的值

uint8_t Key_Down_Count_Flag = 0;//按键按下次数的值,用于判断是单击还是双击

uint8_t Key_Down_Flag = 0;		//按键按下标志位,防止一直按着导致按键次数一直增加

uint16_t Key_Click_Time = 0;	//按键次数为1时开始计时,其他状态为0



void Key_Init(void) //初始化12个按键引脚
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
		
	GPIO_InitStructure.GPIO_Pin = KYE10_GPIO_PIN|
								  KYE8_GPIO_PIN|
								  KYE7_GPIO_PIN|
								  KYE6_GPIO_PIN|
								  KYE5_GPIO_PIN|
								  KYE4_GPIO_PIN|
								  KYE3_GPIO_PIN|
								  KYE1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);	
	
	GPIO_InitStructure.GPIO_Pin = KYE2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = KYE9_GPIO_PIN|
																KYE11_GPIO_PIN|
																KYE12_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOC,&GPIO_InitStructure);	
}

/*
* 描述:  返回key1控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key1_State(void)
{
	if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY1_GPIO,KYE1_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}

/*
* 描述:  返回key2控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key2_State(void)
{
	if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY2_GPIO,KYE2_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}

/*
* 描述:  返回key3控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key3_State(void)
{
	if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY3_GPIO,KYE3_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}

/*
* 描述:  返回key4控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key4_State(void)
{
	if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY4_GPIO,KYE4_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}

/*
* 描述:  返回key5控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key5_State(void)
{
	if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY5_GPIO,KYE5_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
* 描述:  返回key6控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key6_State(void)
{
	if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY6_GPIO,KYE6_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
* 描述:  返回key7控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key7_State(void)
{
	if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY7_GPIO,KYE7_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}

/*
* 描述:  返回key8控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key8_State(void)
{
	if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY8_GPIO,KYE8_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}


/*
* 描述:  返回key9控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key9_State(void)
{
	if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY9_GPIO,KYE9_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
* 描述:  返回key10控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key10_State(void)
{
	if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY10_GPIO,KYE10_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
* 描述:  返回key11控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key11_State(void)
{
	if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY11_GPIO,KYE11_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
* 描述:  返回key12控制键的状态  
* 参数:  无
* 返回值:0按下 1没按下
*/
uint8_t Get_Key12_State(void)
{
	if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
	{
		Delay_Ms(10);
		if(GPIO_ReadInputDataBit(KEY12_GPIO,KYE12_GPIO_PIN) == RESET)
		{
			return 0;
		}	
	}
	return 1;
}
/*
*描述:		判断只有一个按键按下
*参数:		无
*返回值:	1:有按键按下,0:无按键按下
*/
uint8_t Key_Down_Num(void)
{
	if(0 == Get_Key1_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key1_State())
		{
			Key_State |= KEY1_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY1_STATE_VALUE;
	}

///
	if(0 == Get_Key2_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key2_State())
		{
			Key_State |= KEY2_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY2_STATE_VALUE;
	}

///
	if(0 == Get_Key3_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key3_State())
		{
			Key_State |= KEY3_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY3_STATE_VALUE;
	}

///
	if(0 == Get_Key4_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key4_State())
		{
			Key_State |= KEY4_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY4_STATE_VALUE;
	}

///
	if(0 == Get_Key5_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key5_State())
		{
			Key_State |= KEY5_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY5_STATE_VALUE;
	}

///
	if(0 == Get_Key6_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key6_State())
		{
			Key_State |= KEY6_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY6_STATE_VALUE;
	}

///
	if(0 == Get_Key7_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key7_State())
		{
			Key_State |= KEY7_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY7_STATE_VALUE;
	}

///
	if(0 == Get_Key8_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key8_State())
		{
			Key_State |= KEY8_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY8_STATE_VALUE;
	}

///
	if(0 == Get_Key9_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key9_State())
		{
			Key_State |= KEY9_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY9_STATE_VALUE;
	}

///
	if(0 == Get_Key10_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key10_State())
		{
			Key_State |= KEY10_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY10_STATE_VALUE;
	}

///
	if(0 == Get_Key11_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key11_State())
		{
			Key_State |= KEY11_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY11_STATE_VALUE;
	}	
	
///
	if(0 == Get_Key12_State())
	{
		Delay_Ms(10);
		if(0 == Get_Key12_State())
		{
			Key_State |= KEY12_STATE_VALUE;
		}
	}
	else
	{
		Key_State &= ~KEY12_STATE_VALUE;
	}	
///	
	Key_State &= 0x0fff;
	if(Key_State != 0)
	{
		return 1;
	}
	return 0;	
}

/*
*描述:		按键检测
*参数:		无
*返回值:	无
*/
void Key_Scanf(void)
{
	if(1 == Key_Down_Num())//判断是否有按键按下
	{
		Old_Key_Value = Key_Value; //每一次按下记录上一次按键的值
		switch(Key_State) //判断按键状态值
		{
			case KEY1_STATE_VALUE:Key_Value = 1;break;
			case KEY2_STATE_VALUE:Key_Value = 2;break;
			case KEY3_STATE_VALUE:Key_Value = 3;break;
			case KEY4_STATE_VALUE:Key_Value = 4;break;
			case KEY5_STATE_VALUE:Key_Value = 5;break;
			case KEY6_STATE_VALUE:Key_Value = 6;break;
			case KEY7_STATE_VALUE:Key_Value = 7;break;
			case KEY8_STATE_VALUE:Key_Value = 8;break;						
			case KEY9_STATE_VALUE:Key_Value = 9;break;		
			case KEY10_STATE_VALUE:Key_Value = 10;break;
			case KEY11_STATE_VALUE:Key_Value = 11;break;
			case KEY12_STATE_VALUE:Key_Value = 12;break;			
			default:Key_Value = 0;break;			
		}		
		if(Key_Down_Flag == 1)
		{
			Key_Down_Count_Flag++; //记录按键按下去的次数			
		}
		Key_Down_Flag = 0;		
	}
	else
	{
		Key_Down_Flag = 1;
	}
	
}

/*
*描述:判断是否是有效键值
*参数:无
*返回值:无
*/
void GetKey_True_Touch(void)
{
	if(Key_Down_Count_Flag == 1) //按下1次
	{
		if(Key_Down_Flag == 0) //按键按下
		{
			//定时器超过长按规定时间
			if(Key_Click_Time >= Key_Long_Click_Time)
			{
				Key_Ture_Value = Key_Value;
			}
			else
			{
				Key_Ture_Value = 0;
			}			
		}
		else	///按键松开
		{
			//判断定时器时间是否超过规定时间
			//如果超过规定时间,清零变量
			if(Key_Click_Time > Key_Two_Click_Time)
			{
				Key_Ture_Value = 0;				//输出值清零				
				Key_Click_Time = 0;				//定时器时间清零
				Key_Down_Count_Flag = 0;	//按键次数清零
			}
		}	
	}
	else if(Key_Down_Count_Flag == 2)//按下2次
 	{
		//如果两次按键值相等,说明双击的是同一个按键
		//如果两次按键值不相等,输出0;
		if(Old_Key_Value == Key_Value)
		{
			Key_Ture_Value = Key_Value;
		}
		else
		{
			Key_Ture_Value = 0;				//输出值清零	
		}
		Key_Click_Time = 0;				//定时器时间清零
		Key_Down_Count_Flag = 0;	//按键次数清零
		while(Key_Down_Num());    //等待按键松开
	}
	
}

//定时器配置//

void TIM2_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;	
	NVIC_InitTypeDef 				NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	
	//配置周期为5ms
	TIM_TimeBaseInitStructure.TIM_Period = 4999;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ARRPreloadConfig(TIM2,ENABLE);//在ARR上启用或禁用TIMx外设预加载寄存器。
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	TIM_Cmd(TIM2,ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
	
	NVIC_Init(&NVIC_InitStructure);
}	
//中断服务函数
void TIM2_IRQHandler(void)
{
	while(TIM_GetFlagStatus(TIM2,TIM_FLAG_Update))
	{
		//按键单击,双击,长按监测
		if(Key_Down_Count_Flag == 1)
		{
			Key_Click_Time++;
			if(Key_Click_Time > Key_Long_Click_Time)
			{
				Key_Click_Time = Key_Long_Click_Time;
			}			
		}
		else
		{
				Key_Click_Time = 0;
		}
		TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
	}	
}

 

  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值