stm32 利用定时器中断消除按键抖动

 

 

button.c

int iButtonCount;//i代表int型变量,ButtonCount表示按键计数变量
int iButtonFlag;//i代表int型变量,ButtonFlag表示重按键标志,1代表重新按键,0为没有重新按键
int g_iButtonState;//g是globle代表全局变量,会在其他地方引用;i代表int型变量,ButtonState表示按键标志,1代表按下,0代表松开
void ButtonScan(void)
{
    if( HAL_GPIO_ReadPin(Button_GPIO_Port,Button_Pin) == GPIO_PIN_RESET )//如果引脚检测到                低电平
    {
    iButtonCount++; //按键按下,计数iButtonCount加1
        if(iButtonCount>=30) //1ms中断服务函数里运行一次,iButtonCount大于等于30,即按键已稳定按下30ms
        {
            if(iButtonFlag==0) //判断有没有重按键,1为有,0为没有
            {
                g_iButtonState=1; //设置按键标志
                iButtonCount=0;
                iButtonFlag=1; //设置重按键标志
            }
            else //如果重按键,则重新计数
            iButtonCount=0;
        }
        else //如果没有稳定按下30ms,则代表没有按下按键
            g_iButtonState=0;
    }
    else //如果一直无检测到低电平,即一直无按键按下
    {
        iButtonCount=0; //清零iButtonCount
        g_iButtonState=0; //清除按键标志
        iButtonFlag=0; //清除重按键标志
    }
}

 

stm32fxx_it.c 文件里面 SysTick_Handler() 函数中添加 

ButtonScan();

 

main.c

if(g_iButtonState == 1)
{
    HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//翻转LED引脚(PB12)的电平
}

 

### STM32定时器中断控制按键实现 #### 使用场景描述 在嵌入式开发中,利用STM32定时器中断可以有效地管理按键输入的时间特性,比如抖动处理或是检测长时间按压情况。这种方式不仅提高了系统的响应速度还增强了稳定性。 #### 硬件连接说明 通常情况下,按键的一端接地(GND),另一端接至MCU的一个GPIO引脚上;该GPIO配置成输入模式并启用内部上拉电阻。当按下按钮时,对应的IO口电平会由高变低[^1]。 #### 软件设计思路 为了防止因机械开关引起的信号波动影响程序判断,在软件层面加入延时函数模拟硬件滤波效果。这里采用TIMx定时器产生的周期性溢出事件触发NVIC中的相应IRQ通道执行特定的服务例程(即ISR)完成状态读取与逻辑运算操作。 #### 关键代码片段展示 ```c // 初始化定时器 TIM6 配置为 1ms 的更新频率 void Timer_Init(void){ __HAL_RCC_TIM6_CLK_ENABLE(); // 开启时钟使能 TIM_HandleTypeDef htim; htim.Instance = TIM6; htim.Init.Prescaler = SystemCoreClock / 1000 - 1 ; htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = 999; HAL_TIM_Base_Init(&htim); HAL_TIM_Base_Start_IT(&htim); } // 中断服务子程序定义 void TIM6_DAC_IRQHandler(void){ if (__HAL_TIM_GET_FLAG (&htim, TIM_FLAG_UPDATE ) != RESET && __HAL_TIM_GET_IT_SOURCE (&htim,TIM_IT_UPDATE)!=RESET ){ Key_Scan(); __HAL_TIM_CLEAR_IT (&htim , TIM_IT_UPDATE ); } } ``` 上述代码实现了每毫秒一次进入`Key_Scan()`函数检查是否有按键动作发生,并清除标志位以便下次正常工作。 #### 按键扫描算法举例 ```c #define KEY_DOWN_LEVEL GPIO_PIN_RESET static uint8_t key_state=0; void Key_Scan(){ static uint16_t cnt=0; if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)==KEY_DOWN_LEVEL){ ++cnt; if(cnt>=50){//约等于50ms防时间 switch(key_state){ case 0:key_state++;break;//首次按下记录 default:if((++key_state)>=(uint8_t)(SystemTick/10)){//超过一秒则认为长按 /* 执行长按时的任务 */ while (HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)==KEY_DOWN_LEVEL);//等待松开 key_state=0; }else{/*短按后的其他处理*/} } cnt=0; } }else{ cnt=0; } } ``` 这段伪码展示了如何区分长短按以及多次点击的情况,其中`SystemTick`代表系统滴答计数器变量名,实际应用需替换为自己项目里的对应部分。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值