2012-08-29 58 views
0

我面臨着LPC17xx系列外部中斷的奇怪問題。恩智浦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 
    } 
} 

「在此工作」部分可能需要一些時間(例如,在某些情況下超過200ms)。這是計劃的進一步執行,並且沒有問題。

問題是,當ISR首先進入並且我在ISR執行的時候再次按下按鈕(這必須快速完成),則掛起的中斷被設置,並且如果ISR再次執行第一次結束。這是我猜想的正常行爲,因爲EXTI_ClearEXTIFlag(1)不會清除NVIC中的任何未決中斷。因此,我添加了NVIC_ClearPendingIRQ(EINT1_IRQn)來清除ISR代碼中多個位置上的新掛起中斷,以確保掛起的中斷被清除。奇怪的是,這根本不起作用。

我的一些問題是,我怎樣才能通過JTAG /調試器(內存地址?)讀取掛起的中斷。這裏發生了什麼?有人可以解釋這種行爲,也許有線索如何解決它?

謝謝!

+0

這是一個奇怪的外觀ISR:有代碼,一個聲明,然後是更多的代碼。你說你添加了一些操作,但不顯示它們並要求進行代碼審查?在200ms的處理後,不應該重置LPC_TIM1-> TC'。順便說一句,在ISR中執行200ms的處理通常是一個壞主意。這通常會引起影響,例如在其他地方增加延遲。你應該考慮實現一個tasklet。 – sawdust

+1

你爲什麼要在isr做這項工作?你需要儘快進出isr。設置一個標誌或增加一個計數器,讓前臺任務看到標誌/計數器並處理按鈕按下。 –

回答

1

當ISR進入第一和我按第二次[...]

這再次觸發EINT1標誌,但後您先清除它的按鈕。這就是爲什麼

NVIC_ClearPendingIRQ(EINT1_IRQn)來清除新掛起的中斷

不起作用,因爲EINT1仍信號中斷線路。您需要後「工作」再打電話

EXTI_ClearEXTIFlag(1);

清除這個標誌。

0

我知道做這麼長的中斷程序通常不是一個好主意。但正如我在問題中所說的那樣,這是有意的。我需要確保在ISR期間不執行主任務中的其他代碼。

但是要回到這個問題:有人指出,將EXTI_ClearEXTIFlag(1)移到ISR的末尾可能是一個好主意。這樣,在執行ISR期間不會產生外部中斷,也不會設置任何掛起。這有效,但我仍然想知道爲什麼清除掛起的中斷不起作用。也許這隻適用於GPIO中斷?

相關問題