清除stm32f103中挂起的EXTI中断

Clearing pending EXTI interrupt in stm32f103

我试图通过切换 PC14 来切换 PC13 的 LED,问题是中断处理程序在不切换 PC14 的情况下一直被调用,并且挂起的中断没有使用 EXTI->PR 寄存器清除,也没有被清除手动使用调试器。我也尝试在 NVIC->ICPR 中清除它,我不确定为什么有两个寄存器用于清除同一个中断。
这是我的代码
你可以在中找到 header https://github.com/AymenSekhri/tinyHAL-STM32f103/tree/master/STM32F103-HAL/tinyHAL

/* 
* Description:
*   Toggle LED at C13 whenever C14 goes from HIGH to LOW.
*
*/
#include "tinyHAL/stm32f103_hal.h"
int main(){
    //Enable AFIO clock from RCC
    enablePeripheralClock(Peripheral_AFIO);
    //Enable and configure C13 & C14
    enablePeripheralClock(Peripheral_GPIOC);
    configureGPIO(Peripheral_GPIOC, 13, GPIO_MODE_OUT_50MHZ, GPIO_CONF_OUT_PUSHPULL);
    configureGPIO(Peripheral_GPIOC, 14, GPIO_MODE_IN, GPIO_CONF_IN_PUSHUP_PULLDOWN);

    //Link EXTI14 to C14
    AFIO->EXTICR[3] = (AFIO->EXTICR[3] & ~(0xF<<8)) | 2;
    //Configure inturrput at EXTI14 falling edge
    EXTI->FTSR      |= 1<<14;
    //Unmask interrupt 40 (EXTI10-15)
    EXTI->IMR       |= 1<<14;
    //Set Priority to interrupt 40 (EXTI10-15)
    NVIC->IP[40]    |= 0x10;

    //Enable interrupt 40 (EXTI10-15)
    NVIC->ISER[40>>5] |= (1 << (40&0x1F));
    while(1);
}

void EXTI15_10_IRQHandler(void){
    toggleGPIOBit(Peripheral_GPIOC, 13);
    if (EXTI->PR & (1 << 14)){
        EXTI->PR |= (1 << 14);
    }
    //NVIC->ICPR[40>>5] |= (1 << (40&0x1F));
    __COMPILER_BARRIER();
}

正如@P__J__建议添加一些谴责逻辑。有两种去抖动方法,例如使用 RC 滤波器和使用软件去抖动逻辑。 由于引脚上的噪声,ISR 正在连续执行。 你可以再检查一件事。 尝试拉动 UP/Down 引脚并观察行为。如果引脚上的逻辑电平没有改变,则不应执行 ISR。

消除引脚上(过度)触发 EXTI 的电子噪声的最佳解决方案是改进硬件 - 但这是软件板,而不是 the electronic one

如果你有一个 TIM 通道连接到该引脚,我建议使用它来过滤传入的信号。但我认为 PC14 没有定时器。

第二好的解决方案(这就是解决方法已经开始的地方!)是使用定时器(TIM,而不是它的通道),或者建立一个周期性的时基来对引脚进行采样(通过 DMA 或通过 ISR,并将样本送入基于软件的过滤...) - 或者在 EXTI ISR 中停用 EXTI 中断,启动定时器并在定时器到期时重新激活 EXTI 中断。

这两种基于 µC 的方法都很笨拙,显然不如开发一个好的硬件。这并不是说 "good" 硬件不应该在软件中添加一些去抖动或噪声保护!

可能是因为 TAMPER/RTC 第二个输出被重定向到 PC13。我之前在使用 PC13 作为 EXTI 时也遇到了同样的问题。将 BKP_RTCCR->ASOE 设置为 1 以强制其作为永远不会触发的警报输出,因为我没有设置任何 rtc 警报。