第十三届蓝桥杯嵌入式备赛-STM32G431-基础模块调试②按键设置/消抖/长按、计时函数创建及使用

目录

0.前言

1.功能要求

电路原理图

2.STM32Cubemx初始化

3.程序实现

创建实现按键功能所需要的变量

对按键读取函数函数进行宏定义

创建按键扫描函数 Key_Scan()

创建计时函数Task_Time()

在stm32g4xx_it.c中引入Task_Time()

按键扫描标志位Key_Ref使用 

创建按键任务执行函数Key_Task()

按键任务执行标志位Key_Flag使用

4.工程文件


0.前言

这套教程针对于蓝桥杯嵌入式比赛的底层模块调试,针对于比赛进行每个模块的调试,低层模块调试好,对于赛题的实现就会方便很多,虽然有一些应试教育的意味,不过准备这个比赛对于程序整体实现思维还是有着很大帮助,我也从中受益颇多! 

1.功能要求

实现按键的消抖、长按等功能,并能够使用按键实现一些基础功能,创建计时函数,对执行函数频率进行调节。

电路原理图

2.STM32Cubemx初始化

将PB0~PB2、PA0设置为GPIO_Input,其他执行默认操作即可,之后生成代码。

3.程序实现

创建实现按键功能所需要的变量

/*main.c*/

typedef enum
{
	Key_Check,
	Key_Press,
	Key_Release,
	Key_Over,
}Key_State;
Key_State KeyState=Key_Check;//按键状态

uint16_t Key_tt=0;//按键扫描计时标志位
uint16_t Key_Ref=0;//按键扫描标志位
uint16_t Key_Value=0;//按键标志
uint16_t Key_Flag=0;//按键任务执行标志位
uint16_t Key_Press_Time=20;//按键按下时间计时

对按键读取函数函数进行宏定义

/*main.c*/

#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)

创建按键扫描函数 Key_Scan()

函数详细解释在注释中

/*main.c*/

void Key_Scan(void)
{
	switch(KeyState)
	{
		case Key_Check:
			Key_Press_Time=20;//初始化按键按下时间
		    //判断是否有按键被按下
			if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))
			{
				KeyState=Key_Press;
			}
		break;
	
		case Key_Press:
			//判断按键是否仍然被按下(消抖操作)
			if(B1==GPIO_PIN_RESET){Key_Value=1;}//检测是哪个按键被按下
			else if(B2==GPIO_PIN_RESET){Key_Value=2;}
			else if(B3==GPIO_PIN_RESET){Key_Value=3;}
			else if(B4==GPIO_PIN_RESET){Key_Value=4;}
			KeyState=Key_Release;
		break;
		
		case Key_Release:
			if((B1==GPIO_PIN_RESET)||(B2==GPIO_PIN_RESET)||(B3==GPIO_PIN_RESET)||(B4==GPIO_PIN_RESET))
			{
				Key_Press_Time+=20;//对按键按下时间进行计时(判断按键是否长按)
			}
			else
			{
				KeyState=Key_Check;
				Key_Flag=1;//置一个标志位,判断是否执行按键任务
			}
		break;
		default:break;
		
	}
}

创建计时函数Task_Time()

该函数用于计时,控制任务执行的频率。该函数非常重要,在之后的程序编写中,也会扩充该函数,以实现更多的任务计时(在main.h中声明该函数)

/*main.c*/

void Task_Time(void)
{
	if(++Key_tt==10)	{Key_tt=0;Key_Ref=1;}
}

在stm32g4xx_it.c中引入Task_Time()

这里使用滴答定时器进行计时,滴答定时器每1ms执行一次SysTick_Handler()函数,所以我们将Task_Time()放在SysTick_Handler()中,使用Key_tt进行计时,每次增加一个数,当Key_tt等于10之后,清空Key_tt,然后将Key_Ref置1,从而进行后续判断

/*stm32g4xx_it.c*/

extern void Task_Time(void);


/*‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥*/


void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  Task_Time();//计时函数(用户自行添加位置)

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

按键扫描标志位Key_Ref使用 

在主循环中判断Key_Ref标志位,当标志位置1后,执行一次Key_Scan()扫描一次按键,即可以实现每10ms执行一次按键的扫描,以达到对按键的消抖和计时

/*main.c*/

while (1)
  {	
    if(Key_Ref==1)
	{
		Key_Ref=0;//清除标志位
		Key_Scan();
	}
  }

创建按键任务执行函数Key_Task()

这里检测 Key_Value、Key_Press_Time的值即可判断哪个按键被按下,并且可以判断按下时间来判断长按与短按。

void Key_Task(void)
{

	if((Key_Value==1)&(Key_Press_Time>=500))//长按
	{
		Key_Value=0;
		/*按键B1长按执行操作*/

	}
	else if(Key_Value==1)//短按
	{
		Key_Value=0;
		/*按键B1短按执行操作*/

	}
	
	if(Key_Value==2)
	{
		Key_Value=0;
		/*按键B2短按执行操作*/

	}	
	
	if(Key_Value==3)
	{
		Key_Value=0;
		/*按键B3短按执行操作*/

	}
	
	if(Key_Value==4)
	{
		Key_Value=0;
		/*按键B4短按执行操作*/

	}		
	
}

按键任务执行标志位Key_Flag使用

在主循环中添加以下代码即可

/*main.c*/

while (1)
  {
		
	if(Key_Flag==1)
	{
		Key_Flag=0;//清除标志位
		Key_Task();
	}

  }

所有函数书写完毕就可以在按键任务执行函数Key_Task()中编写自己的用户函数啦!

注:main.c中定义的函数请务必在main.h中声明,为方便后续模块的调用!!!

/*main.h*/

void Task_Time(void);
void Key_Scan(void);

相关函数定义位置stm43g4xx_hal_gpio.c

/*stm43g4xx_hal_gpio.c*/

HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);

4.工程文件

该工程文件为全10讲所有内容,可以作为参考,不过还是希望读者能够自己手敲一遍,加深记忆

链接:https://pan.baidu.com/s/1LcNszc7_oHWvXcucCezlxg?pwd=hw07 
提取码:hw07

 自己做的笔记,也希望能对你有帮助!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别人家的孩子380

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值