【蓝桥杯嵌入式笔记】(三)按键实验

 

一、原理图

d2d8e44cbe7abb6be4f28e41d4c556c5.png

二、CubeMX配置

引脚PB0、PB1、PB2、PA0都配置为GPIO_Input,并设置为上拉输入Pull_up

12b8573cd1399082266daf7973ba4c49.png

设置定时器4,1ms,开中断

c725d75898801f50233ae17bca72a111.png

50df7a7a2d01a39ec3c52214baeae3a9.png

三、代码

1.短按

开启定时器中断

HAL_TIM_Base_Start_IT(&htim4);

button放主循环,每1ms扫描一次键值 

void button()
{
	switch(key)
	{
		case 1:
		{
			num++;
			key=0;
		}
		break;
		case 2:
		{
			num--;
			key=0;
		}
		break;
		case 3:
		{
			num=0;
			key=0;
		}
		break;
		case 4:
		{
			num=20;
			key=0;
		}
		break;
		
	}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if( htim->Instance==TIM4 )
	{
		static unsigned char key_old=0;
		unsigned char key_new,key_up,key_down;
		key_new=key_scan();
		key_down=key_new&(key_new^key_old);
		key_up=~key_new&(key_new^key_old);
		key_old=key_new;
		
		if( key_up )
		{
			key=key_up;
		}
	}
}

unsigned char key_scan()
{
    unsigned char key_result=0;//这句话一定不能忘记等于0
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)  key_result=1;
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)  key_result=2;
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)  key_result=3;
    if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)  key_result=4;
    return key_result;
}

 2.长按

 开启定时器中断

HAL_TIM_Base_Start_IT(&htim4);

key和key_n均为全局变量

void key_pro()
{
		switch(key)
		{
			case 1:
			{
				num++;
				key=0;
			}
			break;
			case 2:
			{
				num--;
				key=0;
			}
			break;
			case 3:
			{
				
				key=0;
			}
			break;
			case 4:
			{
				
				key=0;
			}
			break;
		}

		
		switch(key_long)
		{
			case 1:
			{
				num++;
			}
			break;
			case 2:
			{
				num--;
			}
			break;
			case 3:
			{
				
			}
			break;
			case 4:
			{
				
			}
			break;
		}
}



void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if( htim->Instance==TIM4 )
	{
		unsigned char key_new,key_down,key_up;
		static unsigned char key_old=0;
		key_new=key_scan();
		key_down=key_new&(key_new^key_old);
		key_up=~key_new&(key_new^key_old);
		key_old=key_new;
		
		if( key_down )
		{
            long_time=0;
			long_time++;
		}
		
		if( key_up )
		{
			if( long_time<50 )    key=key_up;
		}
		
		if( long_time!=0 )
		{
			long_time++;
		}
		if( long_time>50 )	key_long=key_new;
		
	}
}

 3.双击

  开启定时器中断

HAL_TIM_Base_Start_IT(&htim4);

设置double_time和double_key

在按键松开后计后,大于0.01s,键值不一样(key_double=1),算单击;

 在按键松开后计后,大于0.01s,键值一样(key_double=2),算双击;

void key_pro()
{
	switch(key_double)
	{
		case 1:
		{
			
			key=0;
			key_double=0;
		}
		break;
		case 2:
		{
			
			key=0;
			key_double=0;
		}
		break;
		case 3:
		{
			num[2]++;
			key=0;
			key_double=0;
		}
		break;
		case 4:
		{
			num[2]--;
			key=0;
			key_double=0;
		}
		break;
	}
	
	
	if( time_double>20 )
	{
		switch(key)
		{
			case 1:
			{
				
				key=0;
			}
			break;
			case 2:
			{
				
				key=0;
			}
			break;
			case 3:
			{
				num[0]++;
				key=0;
			}
			break;
			case 4:
			{
				num[0]--;
				key=0;
			}
			break;
		}
	}
	
	
	switch(key_long)
	{
		case 1:
		{
			
			key_long=0;
		}
		break;
		case 2:
		{
			
			key_long=0;
		}
		break;
		case 3:
		{
			num[1]++;
			key_long=0;
		}
		break;
		case 4:
		{
			num[1]--;
			key_long=0;
		}
		break;
	}
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if( htim->Instance==TIM4 )
	{
		static unsigned char key_old=0;
		unsigned char key_new,key_down,key_up;
		key_new=key_scan();
		key_down=key_new&(key_new^key_old);
		key_up=~key_new&(key_new^key_old);
		key_old=key_new;
		
		if( key_up )
		{
			if( time_long<70&&double_1!=11 )	key=key_up;
			
			long_1=0;
			
			time_double=0;
			time_double++;
			if( double_1==11 )	double_1=0;
			else double_1=key_up;
		}
		
		if( key_down )
		{
			time_long=0;
			time_long++;
			long_1=key_down;
			
			if( double_1==key_down&&time_double<=20 )
			{
				double_1=11;
				key_double=key_down;
			}
		}
		
		if( time_long!=0 )	time_long++;
		if( time_long>70 )	key_long=long_1;
		
		if( time_double!=0 )	time_double++;
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值