蓝桥杯嵌入式——KEY

发布时间:2023年12月19日

CUBE里将这几个引脚配置成GPIO输入模式,再同时选中,配置成上拉,如下图:

?

同时配置定时器,定时10ms,每10ms扫描一次按键,计算公式:80 000 000 / 80 / 10000 = 100HZ = 10ms,配置如下图(记得使能中断):

中断文件:

interrupt.c

#include "interrupt.h"

extern uint8_t flag_10ms;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM2)
	{
		flag_10ms = 1;
	}
}

interrupt.h

#ifndef __interrupt_h
#define __interrupt_h

#include "main.h"

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

#endif

?在主函数里打开定时器2中断:

HAL_TIM_Base_Start_IT(&htim2 );

?

?按键文件:

key.c

按键原理:

以代码中的B1为例:每10ms进来一次按键,哪个按键按下对应的t就+1,当松手后就判断t值,大于100(1s)即为长按,大于2小于100(20ms < t < 1000ms)即为短按。

以B2为例:在短按的时候设置一个时间,这里我设置的是500ms,500ms内如果有按键按下,就重置Fcnt = 50,同时Key_cnt + 1;若没有,则当500ms过去后,就判断Key_cnt的值,从而知道多击的次数。在最后,要将Key_cnt,Fcnt清零。

至于组合键,很简单,也感觉不会考。。。。。

#include "key.h"

uint8_t flag_10ms;

uint8_t Key_Scan(void)
{
	uint8_t key_temp = 0;
	static uint8_t t1 = 0;
	static uint8_t t2 = 0;
	static uint8_t Fcnt = 0;//多击按键计时
	static uint8_t Key_cnt = 0;//记录按键多击次数
	
	if(flag_10ms == 1)
	{
		if(B1 == 0) t1++;
		if(B1 == 1)
		{	
			if(t1 > 100)	//长按
			{
				key_temp = 10;
			}
			else if(t1 > 2)//短按(20ms)
			{
				key_temp = 1;
			}
			t1 = 0;
		}
		
		if(B2 == 0) t2++;
		if(B2 == 1)
		{				
			if(t2 > 100)
			{
				key_temp = 20;
			}			
			else if(t2 > 2)
			{
				Key_cnt ++;//多击按键次数+1
				Fcnt = 50;//计时500Ms
			}
			t2 = 0;
			if(Fcnt)
			{
				Fcnt--;
				if(Fcnt == 0)//当没有按键按下时
				{
					if(Key_cnt == 1)//单击
					{
						key_temp = 2;
					}
					else if(Key_cnt == 2)//双击
					{
						key_temp = 22;
					}
					Key_cnt = 0;
					Fcnt = 0;
				}
			}
		}
		
		if(B3 == 0)
		{
			if(B4 == 0)	//组合键
			{
				key_temp = 34;
			}
		}
		
		flag_10ms = 0;
	}
	return key_temp;
}

key.h

#ifndef __key_h
#define __key_h

#include "main.h"

#define B1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define B2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define B3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define B4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)

uint8_t Key_Scan(void);

#endif

main.h

按键处理函数,本例实现按键点灯的功能,如下:

void Key_Pro(void)
{
	switch(Key_Scan())
	{
		case 1://B1短按
			Led_disp(0);
		break;
		case 10://B1长按
			Led_disp(1);
		break;
		case 2://B2短按
			Led_disp(2);
		break;
		case 20://B2长按
			Led_disp(3);
		break;
		case 22://B2双击
			Led_disp(4);
		break;
	}
}

?

文章来源:https://blog.csdn.net/qq_53471484/article/details/135074592
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。