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。
  • 当flag为true时,熄灭 LED(GPIO_PIN_RESET);为false时,点亮 LED(GPIO_PIN_SET)。
  • 执行后翻转flag状态(flag=!flag),并再次停止TIM2(双重保障,防止定时器未正确停止)。

核心逻辑总结

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

相关推荐
lhbweilai13 分钟前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
艾络迅Acceleronix1 小时前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节
涂山苏苏⁠1 小时前
stm32复习总结
stm32·单片机·嵌入式硬件
Zwawa1 小时前
一只按键不只“按下”:短按、长按和连按如何共存
c语言·单片机·嵌入式
苏格拉真没有底2 小时前
ESP32 AI MCP调试器
stm32·单片机·嵌入式硬件
深圳老胡2 小时前
压力检测空吸功能硬件方案全解析:主流压力传感器品牌与实现路径
笔记·单片机·代码规范
硅基造物主3 小时前
STM32 从 0 到 1 做智能家居(二):把开发环境一次配好
stm32·mqtt·智能家居·hal库·esp-12f
zhangzhangkeji4 小时前
stm32, HAL 库,PVD 与低功耗:
stm32
创界工坊工作室6 小时前
50-基AT89C51的自动窗帘控制系统的设计
stm32·单片机·嵌入式硬件·51单片机·proteus
xiangw@GZ6 小时前
SD / eMMC / SDIO 总线接口技术对比
单片机·嵌入式硬件