您当前的位置: 首页 >  stm32
  • 1浏览

    0关注

    483博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

MCU_关于STM32Fxxx中断EXTI产生时多次(两次)进入中断的原因

高精度计算机视觉 发布时间:2020-04-12 13:19:18 ,浏览量:1

调试新的芯片Stm32F407时,发现和以前的不一样。

相同的代码,EXTI中断总是会进入两次,为了验证,我手动在中断中进行了清除,

void EXTI0_IRQHandler(void)
{
    /* USER CODE BEGIN EXTI0_IRQn 0 */

    /* USER CODE END EXTI0_IRQn 0 */
    HAL_NVIC_ClearPendingIRQ(EXTI0_IR0n);    // HAL_GPIO_EXTI_IRQHandler 会做同样的工作
    __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);  // 等价于 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)
    //HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);  // 其中调用了 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); 
    /* USER CODE BEGIN EXTI0_IRQn 1 */
    //if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIO_INPUT_EXTI_PORT, GPIO_INPUT_EXTI_P0))
    Exti_Interrupt(0); //自己写的中断功能函数
    /* USER CODE END EXTI0_IRQn 1 */
}

即使使用了ClearPendingIRQ,也同样会在中断产生时进入两次。以前使用的STM32F1xx芯片没有这个现象,不清楚不同批次之间,会不会有类似的问题。

当然,从程序的角度,对于按键类的操作,一般要求是在Exti_Interrupt中进行debouncing(去抖动)操作,这样是最稳妥的办法。

不过这里纠结的是,为什么会两次进入中断呢?

因为没法弄明白芯片设计,只能猜,大约是硬件在设计时的考量取舍有一定难度,所以导致有的STM32芯片会多次进入,有的不会。

当然,官方STM示例中是不使用HAL_NVIC_ClearPendingIRQ(EXTI0_IRQx)这样的操作的,不敢说这句是否有用。默认不去处理后续的挂起操作,那么不使用这个清除会不会更好,估计得有运气的成份,如果抖动不存在那最好了,貌似我这里不行。

经过搜索,在这里发现了一个比较合理的解释http://www.keil.com/support/docs/3928.htm

在概意思就是和硬件有关。后面还给出了一个解决办法(和去抖动类似),弄一个延时操作在前面。

我把全部原文贴在下面,

ARM: Cortex-M3/M4 Interrupts Happening Twice?

Information in this knowledgebase article applies to:

  • Cortex-M3 and Cortex-M4 Devices
SYMPTOM

Cortex-M3 and Cortex-M4 interrupts appear to be triggering twice.

CAUSE

This may happen with devices:

  • That add an external, system-level write buffer in their Cortex-M3 or Cortex-M4 design, AND
  • The ISR code exits immediately after a write to clear the interrupt.

In this situation, the write to clear the interrupt may not complete before interrupt triggers a second time.

REASON

For the Cortex-M3 and Cortex-M4 cores, writes (STR, STMIA or PUSH) to memory are internally buffered. The Harvard architecture allows the MCU to fetch and execute instructions without waiting for data writes to memory to complete. The Cortex-M cores are aware of the internal buffer and prevent subsequent interrupts until the internal buffer empties and the write completes.

Sometimes vendors incorporate an additional external, system-level write buffer in their Cortex-M3 and Cortex-M4 designs for better performance. But unfortunately, the core is not aware of this external write buffer and cannot access it's status. For these externally-buffered devices, if an ISR exits immediately after clearing the interrupt register, a second interrupt could trigger again before the write to clear the interrupt completes.

For example, this ISR exits immediately after clearing the timer interrupt. Without the external buffer implementation, this code would work as expected. However, on a device with an external, system-level write buffer, this code could cause this "double IRQ" condition:

void Timer_IRQHandler (void) {
  Timeout_counter++;                /* Increment timeout counter */
  PortD->PTOR |= 1PTOR |= 1PTOR |= 1PTOR = PortD->PTOR;        /* Insure IRQ clear          */
}

Last Reviewed: Wednesday, June 14, 2017

 

关注
打赏
1661664439
查看更多评论
立即登录/注册

微信扫码登录

0.0371s