找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 252|回復: 10
打印 上一主題 下一主題
收起左側(cè)

STM32單片機外部中斷結(jié)束后的返回問題

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:205485 發(fā)表于 2025-5-12 23:46 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
     大家好!我最近在學習STM32的外部中斷,遇到一個問題,在這里請教大家。因為程序簡單,附件里也有程序,所以就不畫圖了,大致描述一下:
1,用STM32F103C8T6的最小系統(tǒng)寫了一個最簡單的程序,主程序里就一個while(1),里面是讓一個LED燈循環(huán)閃爍。
2,在主程序基礎(chǔ)上,增加了一個外部中斷,按下按鍵則進入中斷,在中斷里LED燈閃爍兩次。
      程序正常運行,上電LED閃爍,按下按鍵可以進入中斷,也能觀察到燈閃爍兩次。但是,中斷執(zhí)行完后,程序并不是返回while(1)里讓燈繼續(xù)閃爍,而是停止了(燈熄滅狀態(tài))。再次按下按鍵,仍然可以進入中斷,仍然不返回主程序的while(1)。
     初學者,水平很差,我想問一下,中斷執(zhí)行完畢后,不是返回主程序繼續(xù)執(zhí)行中斷前的程序嗎?是我的理解不對嗎?
     中斷里已經(jīng)清除了標志位的。附件里是程序,文件BUZZER是燈,METAL是按鍵及中斷。謝謝。

外部中斷.7z

183.82 KB, 下載次數(shù): 0

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:205485 發(fā)表于 2025-5-13 08:39 | 只看該作者








這是原理圖和程序,原理圖就是一個最小系統(tǒng),兩個箭頭PA8是按鍵,PB1是LED燈,其他IO口可忽略

回復

使用道具 舉報

板凳
ID:744809 發(fā)表于 2025-5-13 08:46 | 只看該作者
中斷里面不要放軟件延時函數(shù),另外中斷里面的代碼一定要精簡,最好控制在100us以內(nèi)
回復

使用道具 舉報

地板
ID:469589 發(fā)表于 2025-5-13 09:33 | 只看該作者
應(yīng)該是中斷級別的我問題,高級中斷里調(diào)用了更高級中斷DELAY(SYSTICK).
回復

使用道具 舉報

5#
ID:592807 發(fā)表于 2025-5-13 09:52 | 只看該作者
嗯,一般人很少會在中斷里面用放延時函數(shù)的,像你這種直接在中斷里面放4個delay_ms(500)加一個delay_ms(100),更加少見,大概就像,你正常情況下每秒鐘必須呼吸一次(中斷需要要循環(huán)訪問,后臺自動控制決定的),然后你訓練拳法,沒呼吸一次要打300拳法(你一個中斷占用了2秒多),你不管你的肺抗不扛得住,憋暈過去也要打完300拳法(你也不管其他中斷會不會沖突是吧,),打完拳你也不呼氣(按鍵中斷的標簽去除了,但是按鍵彈起來了嗎)
void EXTI9_5_IRQHandler(void)
{
         
   if(EXTI_GetITStatus(EXTI_Line8)==SET)
        {
                Delay_ms(100);
         if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0)
         {
                  Buzzer_ON();
                  Delay_ms(500);
                  Buzzer_OFF();
                  Delay_ms(500);
                  Buzzer_ON();
                  Delay_ms(500);
                  Buzzer_OFF();
                  Delay_ms(500);
         }
          
        }
          EXTI_ClearITPendingBit(EXTI_Line8);
}
回復

使用道具 舉報

6#
ID:205485 發(fā)表于 2025-5-13 10:40 | 只看該作者
謝謝大家,我剛才把延時全部調(diào)整成了1毫秒,問題依然存在。估計是前面那個朋友說的,是延時函數(shù)的優(yōu)先級問題。
回復

使用道具 舉報

7#
ID:205485 發(fā)表于 2025-5-13 12:59 | 只看該作者
中斷里只要有延時函數(shù),不論長短(即使幾微秒),都會卡死;注釋掉延時函數(shù),就好了。
回復

使用道具 舉報

8#
ID:685462 發(fā)表于 2025-5-14 00:06 | 只看該作者
紅花無常 發(fā)表于 2025-5-13 10:40
謝謝大家,我剛才把延時全部調(diào)整成了1毫秒,問題依然存在。估計是前面那個朋友說的,是延時函數(shù)的優(yōu)先級問 ...

void Delay_us(uint32_t xus)
{
        SysTick->LOAD = 72 * xus;                                //設(shè)置定時器重裝值
        SysTick->VAL = 0x00;                                        //清空當前計數(shù)值
        SysTick->CTRL = 0x00000005;                                //設(shè)置時鐘源為HCLK,啟動定時器
        while(!(SysTick->CTRL & 0x00010000));        //等待計數(shù)到0
        SysTick->CTRL = 0x00000004;                                //關(guān)閉定時器
}
打個斷點仿真下就看到了,中斷運行后卡到了deay函數(shù)等待計數(shù)到0。感覺是在main中delay時,進入中斷,中斷delay后閉定時器,中斷完回到main中的delay,這時的計數(shù)器已經(jīng)關(guān)閉了?ǖ健皐hile(!(SysTick->CTRL & 0x00010000));”這一句。在while中添加個檢測計數(shù)器是否關(guān)閉,如果關(guān)閉的,打開計時器。

        while(!(SysTick->CTRL & 0x00010000))        //等待計數(shù)到0
        {
                if(SysTick->CTRL == 0x00000004)
                {

              SysTick->CTRL = 0x00000005;                                //設(shè)置時鐘源為HCLK,啟動定時器                       
                }
                       
                       
回復

使用道具 舉報

9#
ID:205485 發(fā)表于 2025-5-14 12:02 | 只看該作者
lose2836 發(fā)表于 2025-5-14 00:06
void Delay_us(uint32_t xus)
{
        SysTick->LOAD = 72 * xus;                                //設(shè)置定時器重裝值

      謝謝!看來問題應(yīng)該就是出在這里。主函數(shù)里有DELAY,主函數(shù)正在執(zhí)行DELAY時,發(fā)生了中斷,中斷函數(shù)里也有DELAY,中斷函數(shù)里執(zhí)行完DELAY后,關(guān)閉了計時器,導致主函數(shù)里的DELAY也關(guān)閉了。
      所以如果在中斷函數(shù)里需要延時,最好是用定時計數(shù)器重新寫一個。
回復

使用道具 舉報

10#
ID:401564 發(fā)表于 2025-5-14 12:39 | 只看該作者
1,中斷中不要做太多的任務(wù),delay這種延時更加不要加,不管是按鍵也好,ADC也好,還是其它的什么,中斷事件只要觸發(fā)某個事件的標志就可以了,再在主函數(shù)中根據(jù)對應(yīng)的標志進行處理
比如ADC,串口之類的,就只管把數(shù)據(jù)保存就可以了,不要在中斷中處理,當然,STM32有DMA,那是以后的事了
2,長時間延時,可以用定時器來進行,類似于SysTick的方式,不要死等,讓單片機500mS什么事都不做,這不是一個好習慣
回復

使用道具 舉報

11#
ID:205485 發(fā)表于 2025-5-14 21:35 | 只看該作者
Y_G_G 發(fā)表于 2025-5-14 12:39
1,中斷中不要做太多的任務(wù),delay這種延時更加不要加,不管是按鍵也好,ADC也好,還是其它的什么,中斷事件只要 ...

好的,謝謝。原則我明白了,具體是通過何種方式實現(xiàn)呢?比如,在觸發(fā)中斷后,有一連串的操作,耗時6-7秒,F(xiàn)在我知道,不能在中斷中處理這么多任務(wù),只能在主程序里處理。那么,該怎么通知主程序呢?是讓主程序不斷在while循環(huán)里掃描,看中斷標志位是否為1嗎?那樣的話,是不是都可以不用外部中斷了,直接在主程序里掃描那個IO口的電平判斷按鈕是否按下即可。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表