基于定时器的按键检测,HAL库模块

一、硬件I2CHAL库配置

1、配置时钟树

根据自己使用的芯片和具体需求配置,我使用的是stm32f103c8t6芯片,晶振配置为8,设置72MHZ分频。

2、打开RCC外部时钟

3、打开Debug

4、配置GPIO引脚

(1)选择引脚

根据具体需求选择GPIO引脚配置成输入模式,上拉输入。博主这里选择·的是PA0,PB1,PB2,PB3这四个引脚。点击引脚选择GPIO_Input。

(2)配置上拉输入

点击System Core,选择GPIO,再选中自己配置的引脚,如下图中的(3)选择Pull- up

5、配置定时器

选择Timers,根据具体需求选择定时器,博主这里选择的是TIM4定时器,时钟配置成外部时钟Internal CIock,设置预分频为80HZ,分频是从零开始,所以要减1。重装载值设置为10000,同理也需要减1。

此时的输出频率=80M/预分频/重装载值=100HZ,即等于10毫秒。

6、生成工程

二、代码部分

(1)定时器按键代码

GPIO引脚配置为上拉输入,所以引脚未按下时为高电平1,按下时引脚为低电平0。

首先在(key.h)文件中定义一个结构体。如下代码。

#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_

#include "main.h"

struct keys
{
	char key_dat;//按键数据标志位
	char key_judge;//按键按下的判断位
	char key_flag;//按下标志位
	char key_longflag;//长按标志位
	char key_time;//按键时间标志位
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);


#endif 

以下是key.c文件代码,注意按键按下时为低电平0,松开时为高电平1。

#include "interrupt.h"
#include  "tim.h"
struct keys key[4]={0,0,0,0,0,};//定义结构体数组存放数据
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	uint i=0;
	if(htim->Instance==TIM4)
	{
		key[0].key_dat=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);//数据位读取GPIO引脚高低电平
		key[1].key_dat=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_dat=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_dat=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		
	for(i=0;i<4;i++)
	{
		switch(key[i].key_judge)//按键判断位,判断按键是否按下,总共判断三次消除抖动
		{
			case 0:
			{
				if(key[i].key_dat==0)//如果按键按下
				{
					key[i].key_judge=1; //按键按下判断位配置为1,进入下一次判断
					key[i].key_time=0;//时间为零
				}
			}
			break;
			case 1:
			{
				if(key[i].key_dat==0)//重复判断按键按下,消除抖动
				{
					key[i].key_judge=2;
				}
				else
				{
					key[i].key_judge=0;//如果按键未按下,判断位归零。再重复消抖操作
				}
			}
			break;
			case 2:
			{
				if(key[i].key_dat==1)按键未按下,判断位归零。再重复消抖操作
				{
					key[i].key_judge=0;
				}
				else               
				{
					key[i].key_time++;//按键按下,时间位不断自加1
					if(key[i].key_time<100)
					{
						key[i].key_flag=1;//时间位小于100,短按标志置1
					}
					else
					{
						key[i].key_longflag=1;//反之长按标志位置1
					}
				}
			}
			break;
		}
	}		
	}

(2)读取按键代码

按键读取代码相对简单,以下是一个实例,博主在此不再赘述。

uint8_t Key_GetNum(void)
{
	int KeyNum=0;
	if (HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0)
	{	
			HAL_Delay(20);
		    while (HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)== 0);//消除抖动操作
		    HAL_Delay(20);
		    KeyNum=1;

	}
	
	return KeyNum;
}

以下是按键代码的使用,将此代码放进main.c文件中便可实现按键功能。

		  
     if(KeyNum ==1)//按键按下
	  {
		  HAL_Delay(20);
		  //以下是自行添加按键工能
		  y++;
		  s++;
	      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
		  HAL_Delay(20);

		  
		  KeyNum =0;//按键标志位清零
	  }

  • 32
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
回答: 在STM32中,使用HAL库实现按键中断可以通过以下步骤进行。首先,在gpio.c文件中定义一个标志位Flag,并在HAL_GPIO_EXTI_Callback函数中对Flag进行取反操作。然后,在gpio.h文件中声明Key_Get_flag函数用于获取Flag的值。在main.c文件的主循环中,通过调用Key_Get_flag函数来判断按键是否按下,并根据判断结果控制GPIO引脚的输出状态。\[1\] 另外,如果需要在中断回调函数中打印信息,可以使用printf函数。在HAL_GPIO_EXTI_Callback函数中,可以通过判断GPIO_Pin来确定是哪个按键触发了中断,并在条件满足时使用printf函数打印相应的信息。\[2\] 在Cortex-M3中,中断优先级可以分为抢占优先级和子优先级。具有高优先级的中断可以打断低优先级的中断,实现中断嵌套。这意味着当一个中断正在执行时,如果有更高优先级的中断发生,系统会立即切换到更高优先级的中断处理函数。\[3\] #### 引用[.reference_title] - *1* *3* [HAL库设置STM32中断](https://blog.csdn.net/qq_39240700/article/details/122951846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32按键中断(HAL库版)](https://blog.csdn.net/iamyangbei/article/details/128172655)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暴打曦晨不加盐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值