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;
        }   
    }
}

回答: 在STM32,使用HAL库实现按键中断可以通过以下步骤进行。首先,在gpio.c文件定义一个标志位Flag,并在HAL_GPIO_EXTI_Callback函数对Flag进行取反操作。然后,在gpio.h文件声明Key_Get_flag函数用于获取Flag的值。在main.c文件的主循环,通过调用Key_Get_flag函数来判断按键是否按下,并根据判断结果控制GPIO引脚的输出状态。\[1\] 另外,如果需要在中断回调函数打印信息,可以使用printf函数。在HAL_GPIO_EXTI_Callback函数,可以通过判断GPIO_Pin来确定是哪个按键触发了中断,并在条件满足时使用printf函数打印相应的信息。\[2\] 在Cortex-M3中断优先级可以分为抢占优先级和子优先级。具有高优先级的中断可以打断低优先级的中断,实现中断嵌套。这意味着当一个中断正在执行时,如果有更高优先级的中断发生,系统会立即切换到更高优先级的中断处理函数。\[3\] #### 引用[.reference_title] - *1* *3* [HAL库设置STM32中断](https://blog.csdn.net/qq_39240700/article/details/122951846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32按键中断HAL库版)](https://blog.csdn.net/iamyangbei/article/details/128172655)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值