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

目录

[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;
        }   
    }
}
相关推荐
Meraki.Zhang1 小时前
【STM32实践篇】:最小系统组成
stm32·单片机·嵌入式硬件·最小系统
Do vis8243 小时前
STM32第二十一天定时器TIM
stm32·单片机·嵌入式硬件
丁满与彭彭4 小时前
嵌入式学习笔记--MCU阶段--day03中断
笔记·单片机·学习
森焱森4 小时前
一文理解锂电池充电、过放修复与电量测量:从原理到实战
c语言·单片机·架构
熬夜的猪仔6 小时前
【Freertos实战】零基础制作基于stm32的物联网温湿度检测(教程非常简易)持续更新中.........
stm32·嵌入式硬件·物联网
景彡先生8 小时前
STM32中的RTC(实时时钟)详解
stm32·嵌入式硬件·实时音视频
代码改变世界ctw8 小时前
2.2 TF-A在ARM生态系统中的角色
汇编·arm开发·安全·trustzone·atf·optee
baynk14 小时前
逆向入门(9)汇编篇-bound指令的学习
汇编·学习
网易独家音乐人Mike Zhou17 小时前
【Linux应用】开发板USB共享网络,网线或USB以太网共享网络(局域网连接PC和开发板,实现PC给开发板共享网络,USB通过NDIS驱动共享)
linux·网络·单片机·mcu·物联网·嵌入式·iot
森焱森20 小时前
单片机中 main() 函数无 while 循环的后果及应对策略
c语言·单片机·算法·架构·无人机