STM32——使用定时器+按键中断来实现长按事件检测触发

复制代码
#include "main.h"
#include "tim.h"
void Key_ExitEvent()
{
	static bool flag=true;
	if(flag)
	{
		HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
	}
	flag=!flag;
	HAL_TIM_Base_Stop_IT(&htim2);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==KEY1_Pin)
	{
		if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
		{
		//去除定时器 2(TIM2)的更新中断标志位(UIF) 的宏函数
		//防止定时器中断上电误触发
		__HAL_TIM_CLEAR_FLAG(&htim2, TIM_SR_UIF); 
		htim2.Instance->CNT=0;
		HAL_TIM_Base_Start_IT(&htim2);		
		}
		else
		{
			HAL_TIM_Base_Stop_IT(&htim2);
		}
	}
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM2)
	{
		//进入定时器中断后再次对按键IO口高低电平进行判断,如果此时按键依然按下说明是长按9
		if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==0)
		{
		Key_ExitEvent();		
		}
		HAL_TIM_Base_Stop_IT(&htim2);
	}
	
}

该程序实现 "按键持续按下 3 秒后执行 LED 状态翻转" 的核心执行过程如下,可分为 4 个关键阶段:

1. 按键按下(触发外部中断)

  • 当按键KEY1被按下(假设低电平有效,即HAL_GPIO_ReadPin返回0)时,触发HAL_GPIO_EXTI_Callback中断回调函数。
  • 函数内首先清除定时器TIM2的更新中断标志位(UIF),防止上电时误触发。
  • 清零TIM2的计数器(CNT),确保从 0 开始计时,然后启动TIM2的定时中断(HAL_TIM_Base_Start_IT),开始 3 秒计时。

2. 定时器计时期间(3 秒内)

  • TIM2以 3 秒为周期运行,计数器从 0 开始累加。
  • 若在 3 秒内松开按键(HAL_GPIO_ReadPin返回1),则再次触发HAL_GPIO_EXTI_Callback,执行else分支:立即停止TIM2定时中断(HAL_TIM_Base_Stop_IT),计时终止,后续无操作。
  • 若 3 秒内持续按下按键,TIM2会继续计时直到 3 秒结束。

3. 定时器 3 秒溢出(触发定时中断)

  • TIM2计时满 3 秒,触发HAL_TIM_PeriodElapsedCallback定时中断回调函数。
  • 函数内首先判断定时器实例为TIM2,然后再次检查按键状态
    • 若按键仍处于按下状态(HAL_GPIO_ReadPin返回0,即持续按下 3 秒),则调用Key_ExitEvent执行操作。
    • 若按键已松开(HAL_GPIO_ReadPin返回1),则不执行任何操作。
  • 无论是否执行操作,最终都会停止TIM2定时中断(HAL_TIM_Base_Stop_IT)。

4. 执行 LED 状态翻转(Key_ExitEvent函数)

  • 该函数通过静态变量flag记录 LED 当前状态,初始为true
  • flagtrue时,熄灭 LED(GPIO_PIN_RESET);为false时,点亮 LED(GPIO_PIN_SET)。
  • 执行后翻转flag状态(flag=!flag),并再次停止TIM2(双重保障,防止定时器未正确停止)。

核心逻辑总结

程序通过 "外部中断启动定时 + 定时中断时二次检查按键状态" 的机制,确保只有当按键持续按下满 3 秒时,才会执行 LED 状态翻转;若中途松开按键,会提前终止计时,不执行任何操作,最终实现 "长按 3 秒触发操作" 的功能。

相关推荐
朱嘉鼎4 小时前
ARM内部寄存器
arm开发·单片机·嵌入式硬件
随机惯性粒子群4 小时前
使用STM32H723VGT6芯片驱动达妙电机
stm32·单片机·嵌入式硬件
嘿嘿嘿x35 小时前
F280025的时钟设置
单片机·嵌入式硬件
GilgameshJSS6 小时前
STM32H743-ARM例程30-Modbus
c语言·arm开发·stm32·单片机·嵌入式硬件
nassi_6 小时前
开发板网络配置
linux·网络·嵌入式硬件
申克Lab6 小时前
STM32 系统定时器(精准延迟)
stm32·单片机·嵌入式硬件
瑞江无限6 小时前
南麟NP3401MR-M-G技术规格与应用全解析
单片机·嵌入式硬件
kuan_li_lyg7 小时前
笛卡尔坐标机器人控制的虚拟前向动力学模型
人工智能·stm32·机器人·机械臂·动力学·运动学·导纳控制
典则7 小时前
STM32FreeRtos入门(五)——同步互斥与通信
java·jvm·stm32