如何修复在 EXTI9-5 上多次触发的中断?

Posted

技术标签:

【中文标题】如何修复在 EXTI9-5 上多次触发的中断?【英文标题】:how do I fix an interrupt that fires multiple times on EXTI9-5? 【发布时间】:2019-10-21 19:42:34 【问题描述】:

我正在研究 STM32F303CC。在这个单片机上,我使用 6 个按钮作为中断。其中 5 个按钮连接到 EXTI15-10,1 个连接到 EXTI9-5。 EXTI15-10 上的按钮工作正常。但是,当我按下 EXTI9-5 上的按钮时,它会触发令人难以置信的次数(随机在 1500 到 4000 次左右之间)。

它清除标志,当中断函数添加断点时,它只触发一次。

我试过看看是否是硬件弹跳,但没有弹跳,用示波器检查过。下降沿和上升沿触发检测也存在这个问题。

我希望在按下后仅触发一次中断,相反,它会触发非常多的次数。

可能是什么问题?

提前致谢, 鲁本

GPIO 配置:

  /*Configure GPIO pins : BUTTON_6_Pin BUTTON_5_Pin BUTTON_4_Pin BUTTON_3_Pin 
                       BUTTON_2_Pin BUTTON_1_Pin BUTTON_7_Pin */
  GPIO_InitStruct.Pin = BUTTON_6_Pin|BUTTON_5_Pin|BUTTON_4_Pin|BUTTON_3_Pin 
                          |BUTTON_2_Pin|BUTTON_1_Pin|BUTTON_7_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

处理程序1:

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)

  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  

处理程序2:

    void EXTI9_5_IRQHandler(void)
        
          /* USER CODE BE

GIN EXTI9_5_IRQn 0 */
    
      /* USER CODE END EXTI9_5_IRQn 0 */
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
      /* USER CODE BEGIN EXTI9_5_IRQn 1 */
    
      /* USER CODE END EXTI9_5_IRQn 1 */
    
    
    /**
      * @brief This function handles EXTI line[15:10] interrupts.
      */
    void EXTI15_10_IRQHandler(void)
    
      /* USER CODE BEGIN EXTI15_10_IRQn 0 */
    
      /* USER CODE END EXTI15_10_IRQn 0 */
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
      HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
      /* USER CODE BEGIN EXTI15_10_IRQn 1 */
    
      /* USER CODE END EXTI15_10_IRQn 1 */
    

【问题讨论】:

不显示代码我们怎么知道有什么问题? 您的示波器可能提供了足够的线路上限 (10-15 pf) 来隐藏去抖动。 这段代码很不完整。 BUTTON_... 定义了什么? 我认为按钮不是触发中断的好选择,因为当它们弹跳时(并且确实如此),您最终会将简单的事情复杂化。进行循环中断并轮询那里的按钮,并进行去抖动。 【参考方案1】:

可能是什么问题?

你有没有考虑过可能是弹跳造成的?

它清除标志,当中断函数添加断点时,它只触发一次。

对我来说,这听起来像是您需要消除按钮 [1][2] 的抖动或添加模拟过滤。

你能和我们分享一下电路图吗?

.

[1]https://www.allaboutcircuits.com/technical-articles/switch-bounce-how-to-deal-with-it/

[2]https://en.wikipedia.org/wiki/Keyboard_technology#Debouncing

【讨论】:

【参考方案2】:

来自 community.st.com 的This 说...

确保它在例程的早期检查并清除标志,然后执行其他操作。如果您在返回之前立即清除它,则会出现尾链问题。

由于这是一个计时/缓存问题,因此增加编译器优化可以使问题出现,而单步执行调试器可以使问题消失。由于它的额外代码(回调等),HAL 可以掩盖问题。

一些解决方案:

在离开 ISR 之前插入同步屏障 (DSB)(提到 here 和 here) 尽早清除中断位 (here) 读/写另一个位置 (here)

我在较新的 STM32H7 变体上看到了同样的问题。

【讨论】:

以上是关于如何修复在 EXTI9-5 上多次触发的中断?的主要内容,如果未能解决你的问题,请参考以下文章

EXTI8_IRQHandler 中断触发多次而不是一次

STM32F030 定时器多次溢出才触发中断的问题

DSP和FPGA之间EMIF连接,使用外部中断上升沿触发,持续时间是多少?

如何配置STM32定时器在每次递增/递减时触发中断?

git rebase 中断后如何修复

STM32:如何配置定时器以在正交编码器模式下每次增量触发中断?