找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6669|回復(fù): 7
收起左側(cè)

關(guān)于stm32外部中斷時(shí)而無法進(jìn)入的問題分析

[復(fù)制鏈接]
ID:230118 發(fā)表于 2020-11-12 16:27 | 顯示全部樓層 |閱讀模式
搞了幾天了,找不到原因,不知各路大神是否有遇到類似問題,提供點(diǎn)建議,問題描述如下:
實(shí)現(xiàn)功能如下,根據(jù)外部中斷EXTI0、EXTI1來改變某個(gè)IO的輸出電平,當(dāng)此IO輸出電平持續(xù)在低電平1ms以上時(shí),觸發(fā)定時(shí)器6,當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI1, 當(dāng)PD8為高電位時(shí),又會(huì)觸發(fā)EXTI0 中斷

STM32外部中斷配置:
  1. void EXTI_Configuration()
  2. {
  3.     EXTI_InitTypeDef EXTI_InitStructure;
  4.     NVIC_InitTypeDef NVIC_InitStructure;
  5. #ifdef   VECT_TAB_RAM
  6.     /* Set the Vector Table base location at 0x20000000 */
  7.     NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
  8. #else   /* VECT_TAB_FLASH   */
  9.     /* Set the Vector Table base location at 0x08000000 */
  10.     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
  11. #endif

  12.     /* Configure the NVIC Preemption Priority Bits */  
  13.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


  14.     EXTI_ClearITPendingBit(EXTI_Line0);
  15.     EXTI_ClearITPendingBit(EXTI_Line1);
  16.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
  17.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
  18.     EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;     //選擇中斷線路0 1


  19.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;         //設(shè)置為中斷請(qǐng)求,非事件請(qǐng)求
  20.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;     //設(shè)置中斷觸發(fā)方式為下降沿觸發(fā)
  21.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;                   //外部中斷使能
  22.     EXTI_Init(&EXTI_InitStructure);
  23.     EXTI->IMR&=~(1|1<<1);

  24.     /*允許EXTI0中斷 */
  25.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  26.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  27.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  28.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  29.     NVIC_Init(&NVIC_InitStructure);

  30.     /*允許EXTI1中斷 */
  31.     NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  32.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  33.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  34.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  35.     NVIC_Init(&NVIC_InitStructure);
復(fù)制代碼
  1. void EXTI0_IRQHandler(void)
  2. {
  3. if (RESET!=(EXTI->PR&EXTI_Line0))
  4. {
  5.         EXTI->PR = EXTI_Line0;
  6.         if (RESET!=(EXTI->IMR&EXTI_Line0))
  7.         {
  8.             TAG.FbCurcuit1 = 1;
  9.             GPIOD->BSRR = GPIO_Pin_8;
  10.             if (0==Hall1)
  11.             {
  12.                 EXTI->IMR&=~(EXTI_Line0);
  13.                 TIM6->SR = (uint16_t)~TIM_IT_Update;
  14.                 TIM6->CR1 &= ((uint16_t)~TIM_CR1_CEN);
  15.                 Hall1 = 1;
  16.             }
  17.             else
  18.             {
  19.                 TIM6->CNT = 0;
  20.                 TIM6->SR = (uint16_t)~TIM_IT_Update;
  21.                 TIM6->CR1 |= TIM_CR1_CEN;
  22.             }
  23.         }
  24.         EXTI->PR = EXTI_Line0;
  25.     }
  26. }

  27. void EXTI1_IRQHandler(void)
  28. {
  29.     if (RESET!=(EXTI->PR&EXTI_Line1))
  30.     {
  31.         EXTI->PR = EXTI_Line1;
  32.         if (RESET!=(EXTI->IMR&EXTI_Line1))
  33.         {
  34.             GPIOD->BRR = GPIO_Pin_8;
  35.             TIM6->SR = (uint16_t)~TIM_IT_Update;
  36.             TIM6->CR1 &= ((uint16_t)~TIM_CR1_CEN);
  37.         }
  38.         EXTI->PR = EXTI_Line1;
  39.     }
  40. }
復(fù)制代碼

啟動(dòng)這個(gè)功能后,運(yùn)行一段時(shí)間后,會(huì)進(jìn)入定時(shí)器6的中斷,跟蹤發(fā)現(xiàn)是某個(gè)EXTI1中斷沒有得到執(zhí)行,檢查了所有相關(guān)的配置以及設(shè)計(jì)到相關(guān)IO操作的地方,沒有發(fā)現(xiàn)異常,現(xiàn)貼出部分跟蹤數(shù)據(jù):

0.png 1.png

在TIM6中斷服務(wù)程序入口處設(shè)置斷點(diǎn),從上面截圖中可以看到 EXTI1 中斷標(biāo)志位PR1 是有被置位的, 但EXTI0 EXTI1 最后一次觸發(fā)時(shí)間是418.00248863,  ,而TIM6觸發(fā)是在 418.00408187, , 可見是因?yàn)镋XTI1未得到執(zhí)行從而導(dǎo)致TIM6未關(guān)閉而進(jìn)入了TIM6中斷,此時(shí)外部中斷PR1已經(jīng)是置位的,為什么EXTI1有發(fā)生中斷卻進(jìn)不了中斷函數(shù)呢,而前面卻一直可以進(jìn)去

3.jpg
上圖是PE0和PE1的輸入,黃色是PE0
外部中斷的頻率大約100k,工作在72M的stm32f103vct6 應(yīng)該是可以承受的吧
回復(fù)

使用道具 舉報(bào)

ID:230118 發(fā)表于 2020-11-13 18:48 | 顯示全部樓層
沉了呀,沒有大佬指點(diǎn)下我嗎,糾正個(gè)錯(cuò)誤
“當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI1, 當(dāng)PD8為高電位時(shí),又會(huì)觸發(fā)EXTI0 中斷”
應(yīng)為當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI0, 當(dāng)PD8為高電位時(shí),又會(huì)觸發(fā)EXTI1 中斷
回復(fù)

使用道具 舉報(bào)

ID:230118 發(fā)表于 2020-11-13 18:54 | 顯示全部樓層
沉了,請(qǐng)大佬們關(guān)注指點(diǎn)下,謝謝
糾正個(gè)錯(cuò)誤:“當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI1, 當(dāng)PD8為高電位時(shí),又會(huì)觸發(fā)EXTI0 中斷”應(yīng)為“當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI0, 當(dāng)PD8為高電位時(shí),又會(huì)觸發(fā)EXTI1 中斷”
回復(fù)

使用道具 舉報(bào)

ID:230118 發(fā)表于 2020-11-14 11:26 | 顯示全部樓層
謝謝樓上的朋友幫頂,貼出中斷優(yōu)先級(jí)配置
    /* Configure the NVIC Preemption Priority Bits */  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_SetPriority(SysTick_IRQn, 2);

    /*NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);*/

    /* Enable the USART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
        
    /* Enable the UART4 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
               
    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;   //搶斷優(yōu)先級(jí)3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                     //響應(yīng)優(yōu)先級(jí)0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //允許中斷
    NVIC_Init(&NVIC_InitStructure);                                                                //寫入設(shè)置


    /* Enable the TIM3 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable the TIM4 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);       

    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);       

    /* Enable the TIM6 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;       
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
回復(fù)

使用道具 舉報(bào)

ID:230118 發(fā)表于 2020-11-14 11:42 | 顯示全部樓層
發(fā)現(xiàn)一點(diǎn)細(xì)節(jié)
出現(xiàn)問題進(jìn)入tim6中斷的前面的情況是,exti0、exti1的中斷在大約1ms的時(shí)間沒有得到執(zhí)行,而恢復(fù)執(zhí)行時(shí),tim6的1ms定時(shí)時(shí)間到了,tim6的中斷子優(yōu)先級(jí)大于exti1,所以進(jìn)了tim6的中斷函數(shù),但是在tim6的中斷函數(shù)的斷點(diǎn)處看到exti1的中斷狀態(tài)位是1,為什么此前的1ms時(shí)間內(nèi)一直得不到執(zhí)行呢,它的優(yōu)先級(jí)是0,我想到的只有兩種可能,一種是有另一個(gè)優(yōu)先級(jí)為0的中斷一直占用,一種是發(fā)生了系統(tǒng)fault或NMI,后者通過trace信息查看是不存在的,前者只有exti0的中斷存在這個(gè)可能,但從代碼看,exti0中斷在中斷函數(shù)頭尾處都有清除,而且其執(zhí)行時(shí)間就1us左右,而硬件測(cè)量exti0觸發(fā)周期有接近10us,而且exti0和exti1是交替觸發(fā)的,也就是說exti0觸發(fā)一次后,后續(xù)如果exti1沒有被觸發(fā),那么exti0不會(huì)被再次觸發(fā),這點(diǎn)從波形圖也可以看出來,太奇怪了,大佬們幫忙分析分析

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:230118 發(fā)表于 2020-11-14 17:44 | 顯示全部樓層
大佬們太忙了,估計(jì)是沒人指點(diǎn)我了,結(jié)帖了,問題湊合解決了,原因只能算是猜測(cè),沒有確切證據(jù):
我測(cè)試過exti0中斷函數(shù)執(zhí)行時(shí)間接近2us,exti1大約1us出頭,加上進(jìn)入和退出中斷的時(shí)間應(yīng)該在6us以內(nèi),理論上頻率可以到150k,我在模擬環(huán)境上測(cè)試就是有漏掉沒執(zhí)行的中斷,上機(jī)測(cè)試,實(shí)際頻率為10K以內(nèi),目前測(cè)試4小時(shí)以上,無異常,只能理解為頻率高了有些中斷能檢測(cè)到邊沿,但是進(jìn)不去中斷服務(wù)程序,具體原因還沒能力分析。
謝謝關(guān)注和幫頂?shù)呐笥选?/td>
回復(fù)

使用道具 舉報(bào)

ID:107913 發(fā)表于 2022-1-27 22:48 | 顯示全部樓層
樓主,我也想問問,我有個(gè)限位器,用的中斷關(guān)閉步進(jìn)電機(jī)使能,問題是這個(gè)有時(shí)候能觸發(fā)中斷,有時(shí)候又不能觸發(fā)中斷.頭都大了
回復(fù)

使用道具 舉報(bào)

ID:1045113 發(fā)表于 2022-9-18 17:43 | 顯示全部樓層
bro0310 發(fā)表于 2020-11-13 18:48
沉了呀,沒有大佬指點(diǎn)下我嗎,糾正個(gè)錯(cuò)誤
“當(dāng)PD8為低電位時(shí),外部電路隔一段時(shí)間后會(huì)觸發(fā)EXTI1, 當(dāng) ...

現(xiàn)在我也遇到了這種情況,剛開始運(yùn)行時(shí)可以進(jìn)中斷 一段時(shí)間后卡死不進(jìn)中斷
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表