HAL库:中断 方式按键检测:抬起执行、按下执行、长按短按检测、延时执行

目录

HAL库:中断 方式按键检测:抬起执行、按下执行、长按短按检测、延时执行

注意事项:

初始化部分:

回调函数部分


HAL库:中断 方式按键检测:抬起执行、按下执行、长按短按检测、延时执行

注意事项:

  • 中断线列表 在stm32xb.h中 有写

  • 中断函数 在.s汇编启动文件中 有写

  • HAL库在各个外设已经做好了检测外部中断等等的函数。对回调函数这些不太理解的 具体见这篇博客HAL库中断处理函数 及 weak弱声明中断回调函数-CSDN博客

  • HAL_Delay阻塞问题

    在这里,消抖的方法时使用较为简单的HAL_Delay的延时函数。

    在ST官方中,对HAL_Delay是这样描述的:

    大概的意思是:HAL_Delay函数是基于系统滴答定时器中断来累增计数产生延时效果。是这表明如果该函数被调用别的中断处理函数里,系统滴答定时器的中断就必须比这个外设中断的优先级高,否则这个外设中断将被阻塞。 (可以理解为,滴答定时器被一个优先级更高的中断给阻塞了。而这个中断又需要大大定时器。)

    这里只学习使用,一般不用这种方式

初始化部分:

  • 输入值为模式。0为按下执行,1抬起执行
  • 根据选择的模式,设置检测上升沿、下降沿进入中断(按键低电平有效)
    • 按下执行:检测下降沿
    • 抬起执行:检测上升沿
  • HAL_Delay阻塞问题:设置滴答定时器为最高优先级
  • 配置优先级和使能中断线
void KEY_Init_IT(uint8_t mode)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();   //开启GPIOB时钟
    
    GPIO_InitTypeDef GPIO_InitStructure;
    
    if(mode == 0)   //判断模式:是否为按下执行
    {
        GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING; //下降沿进入中断 模式
    }
    else    //否则为抬起执行
    {
        GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; //上升沿进入中断  模式
    }
    
    GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_10;
    GPIO_InitStructure.Pull = GPIO_PULLUP; 
    HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);//配置PB 10 、 0的模式
    
    //HAL库默认中断分组为组4 抢占4 响应0
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    
    //设置中断优先级
    HAL_NVIC_SetPriority(EXTI0_IRQn,4,0);   //抢占和响应
    HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能
    
    HAL_NVIC_SetPriority(EXTI15_10_IRQn,4,0);   //抢占和响应(这里设置的抢占优先级更高)
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); //使能
    
    HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置滴答定时器为最高优先级,否则会卡死在HAL_Delay函数中
}

回调函数部分

对抬起和按下分别判断。 在按下有效时只可能进入按下判断部分; 在抬起有效时,只可能进入抬起检测部分。 因为波动导致时间不够会直接退出中断。

//定义 (强声明的) HAL库回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    switch(GPIO_Pin)//根据进入时的Pin值来选择不同的动作
    {
        case GPIO_PIN_0 : 
        {
            if(KEY1_IN == 0)//判断按下
            {
                HAL_Delay(10);      //消抖
                if(KEY1_IN == 0)    //确实按下
                {
                    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
                }
            }
            else if(KEY1_IN == 1)//判断抬起
            {
                HAL_Delay(10);      //消抖
                if(KEY1_IN == 1)    //确实抬起
                {
                    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
                }
            }
            break;
        }
        case GPIO_PIN_10 : 
        {
            if(KEY2_IN == 0)//判断按下
            {
                HAL_Delay(10);      //消抖
                if(KEY2_IN == 0)    //确实按下
                {
                    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
                }
            }
            else if(KEY2_IN == 1)//判断抬起
            {
                HAL_Delay(10);      //消抖
                if(KEY2_IN == 1)    //确实抬起
                {
                    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
                }
            }
            break;
        }   
    }
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32HAL库提供了一些函数和方法来实现按键按、短按和双击功能。下面是一种常见的实现方式: 1. 首先,需要初始化按键引脚和相关的外部中断。可以使用HAL库提供的GPIO_Init()函数来初始化按键引脚,并使用HAL库提供的HAL_GPIO_EXTI_Callback()函数来处理外部中断的回调函数。 2. 在回调函数中,可以使用HAL库提供的HAL_GetTick()函数获取当前系统的滴答计数值,用于计算按键按下时间。 3. 当按键按下时,记录下按下的时间,并在松开按键时计算按键按下的时间差。根据时间差的不同,可以判断出是按、短按还是双击。 4. 根据判断结果,执行相应的操作。例如,如果是按,则执行按操作;如果是短按,则执行短按操作;如果是双击,则执行双击操作。 下面是一个示例代码,演示了如何使用STM32HAL库实现按键按、短按和双击功能: ```c #include "stm32f4xx_hal.h" #define BUTTON_PIN GPIO_PIN_0 #define BUTTON_PORT GPIOA #define LONG_PRESS_TIME 1000 // 按时间阈值 #define DOUBLE_CLICK_TIME 300 // 双击时间阈值 uint32_t buttonPressTime = 0; uint8_t buttonClickCount = 0; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == BUTTON_PIN) { if (HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN) == GPIO_PIN_SET) { // 按键按下 buttonPressTime = HAL_GetTick(); } else { // 按键松开 uint32_t buttonReleaseTime = HAL_GetTick(); uint32_t buttonPressDuration = buttonReleaseTime - buttonPressTime; if (buttonPressDuration >= LONG_PRESS_TIME) { // 按 // 执行按操作 } else if (buttonPressDuration <= DOUBLE_CLICK_TIME) { // 短按 buttonClickCount++; if (buttonClickCount == 2) { // 双击 // 执行双击操作 buttonClickCount = 0; } } else { // 单击 // 执行单击操作 buttonClickCount = 0; } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值