【发布时间】:2012-08-29 18:15:32
【问题描述】:
我遇到了一个关于 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/调试器(内存地址?)读取挂起的中断。这里发生了什么?有人可以解释这种行为并可能知道如何解决它吗?
谢谢!
【问题讨论】:
-
这是一个看起来很奇怪的 ISR:有代码、声明和更多代码。你说你添加了一些操作,但不显示它们并要求代码审查?
LPC_TIM1->TC的重置不应该发生在 200ms 的处理之后吗?顺便说一句,在 ISR 中执行 200 毫秒的处理通常是一个坏主意。这通常会引起影响,例如在其他地方增加延迟。你应该考虑实现一个 tasklet。 -
你为什么要在 isr 工作?你需要尽快进出isr。设置标志或增加计数器,让前台任务查看标志/计数器并处理按钮按下。
标签: embedded microcontroller interrupt lpc