恩智浦LPC17xx等待中断

时间:2012-08-29 18:15:33

标签: embedded microcontroller interrupt lpc

我正面临着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的一部分(包括200ms按钮去抖动计时器):

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 /调试器(内存地址?)读取待处理的中断。这是怎么回事?有人可以解释这种行为,也许有一个线索如何解决它?

谢谢!

2 个答案:

答案 0 :(得分:1)

  

首先输入ISR,然后再次按下按钮[...]

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

  

NVIC_ClearPendingIRQ(EINT1_IRQn)清除新的待处理中断

不起作用,因为EINT1仍然发出中断线的信号。你需要打电话

EXTI_ClearEXTIFlag(1);

在“工作”之后再次清除此标志。

答案 1 :(得分:0)

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

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