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;
        }   
    }
}
相关推荐
weixin_4526006938 分钟前
《青牛科技 GC6125:驱动芯片中的璀璨之星,点亮 IPcamera 和云台控制(替代 BU24025/ROHM)》
人工智能·科技·单片机·嵌入式硬件·新能源充电桩·智能充电枪
weixin_452600692 小时前
【青牛科技】14W 高保真音频放大电路——D2030
科技·单片机·嵌入式硬件·音视频·电动工具·智能电表
小刘同学-很乖9 小时前
MQTT从入门到精通之MQTT Dashboard
spring boot·stm32·物联网·iot
YuCaiH9 小时前
【STM32】USART串口数据包
笔记·stm32·单片机·嵌入式硬件
Kasen's experience12 小时前
STM32 GPIO 配置
stm32·单片机·嵌入式硬件
知行电子-12 小时前
Proteus中数码管动态扫描显示不全(已解决)
单片机·proteus·嵌入式
学习路上_write13 小时前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念13 小时前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
jjjxxxhhh12314 小时前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
无敌最俊朗@14 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习