蓝桥杯嵌入式——KEY
2023-12-19 05:47:07
    		
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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!