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;
        }   
    }
}
相关推荐
国科安芯4 小时前
【AS32系列MCU调试教程】调试工具:Eclipse调试工具栏与窗口的深入分析
单片机·嵌入式硬件·eclipse
nuannuan2311a5 小时前
9N65-ASEMI照明系统应用专用9N65
单片机·嵌入式硬件
woshihonghonga5 小时前
高级定时器TIM1、TIM8
stm32·单片机·嵌入式硬件
腾飞的信仰5 小时前
举例说明单片机,主循环和中断资源访问冲突的案例
单片机·嵌入式硬件·mongodb
腾飞的信仰15 小时前
单片机,主循环和中断资源访问冲突的案例
单片机·嵌入式硬件
花落已飘16 小时前
STM32 Bootloader:使用文件头加载并启动应用程序
stm32·bootloader
猿来不是梦17 小时前
RT_Thread内核源码分析(五)——内存管理@小堆内存管理算法
stm32·单片机·算法·系统架构·rt_thread操作系统
JXNL@18 小时前
STM32外设学习之USB
stm32·嵌入式硬件·学习
aerror1 天前
使用mpu6500/6050, PID,互补滤波实现一个简单的飞行自稳控制系统
单片机·飞控
yifa201604041 天前
STM32、Arduino和51单片机
stm32·学习·51单片机