0

LPC17xx 系列的外部中断遇到了一个奇怪的问题。

我有一个外部按钮设置为外部中断 1,下降沿与内部作为外部上拉电阻(p2.11):

PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = PINSEL_PINMODE_PULLUP;
PinCfg.Pinnum = 11;
PinCfg.Portnum = 2;
PINSEL_ConfigPin(&PinCfg);
GPIO_SetDir(2,((uint32_t)1<<11),0);

和:

EXTICfg.EXTI_Line = EXTI_EINT1;
EXTICfg.EXTI_Mode = EXTI_MODE_EDGE_SENSITIVE;
EXTICfg.EXTI_polarity = EXTI_POLARITY_LOW_ACTIVE_OR_FALLING_EDGE;
EXTI_Config(&EXTICfg);
EXTI_ClearEXTIFlag(EXTI_EINT1);

和:

NVIC_SetPriority(EINT1_IRQn,1);
NVIC_EnableIRQ(EINT1_IRQn);

这是 ISR 的一部分(包括 200 毫秒按钮去抖定时器):

void EINT1_IRQHandler(void)
{
    EXTI_ClearEXTIFlag(1);

    uint32_t tim1Cnt = LPC_TIM1->TC;

    if (tim1Cnt > ButtDebounceUs)
    {
        LPC_TIM1->TC = 0x00000000;

        // Do work here
    }
}

“在这里工作”部分可能需要一些时间(例如,在某些情况下超过 200 毫秒)。这是为了进一步执行程序而没有问题。

问题是,当第一次输入 ISR 并且在 ISR 执行时我第二次按下按钮(这必须快速完成)时,设置了一个挂起的中断并导致 ISR 在第一次结束时再次执行时间。我猜这是正常行为,因为 EXTI_ClearEXTIFlag(1) 不会清除 NVIC 中的任何未决中断。所以我添加了 NVIC_ClearPendingIRQ(EINT1_IRQn) 来清除 ISR 代码中几个位置的新挂起中断,以确保挂起的中断被清除。奇怪的是,这根本不起作用。

我的一些问题是,如何通过 JTAG/调试器(内存地址?)读取挂起的中断。这里发生了什么?有人可以解释这种行为,也许有线索如何解决它?

谢谢!

4

2 回答 2

1

当第一次输入 ISR 并且我第二次按下按钮 [...]

这会再次触发 EINT1 标志,但您先清除它之后。这就是为什么

NVIC_ClearPendingIRQ(EINT1_IRQn) 清除新的挂起中断

does not work, as EINT1 still signals the interrupt line. You need to call

EXTI_ClearEXTIFlag(1);

again after the "work" to clear this flag.

于 2012-09-01T20:48:06.823 回答
0

我知道做这么长的中断程序通常不是一个好主意。但正如我在问题中所说,这是有意的。我需要确保在 ISR 期间没有执行主要任务中的其他代码。

但回到这个问题:其他人指出,将 EXTI_ClearEXTIFlag(1) 移动到 ISR 的末尾可能是一个好主意。这样就不会产生外部中断,也不会在 ISR 执行期间设置任何挂起。这可行,但我仍然想知道为什么清除挂起的中断不起作用。也许这只适用于 GPIO 中断?

于 2012-08-30T07:42:17.230 回答