欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

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

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

外部中斷.7z

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

回復(fù)

使用道具 舉報

ID:205485 發(fā)表于 2025-5-13 08:39 | 顯示全部樓層
電路.jpg
初始化.jpg

中斷.jpg

MAIN函數(shù).jpg


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

回復(fù)

使用道具 舉報

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

使用道具 舉報

ID:469589 發(fā)表于 2025-5-13 09:33 | 顯示全部樓層
應(yīng)該是中斷級別的我問題,高級中斷里調(diào)用了更高級中斷DELAY(SYSTICK).
回復(fù)

使用道具 舉報

ID:592807 發(fā)表于 2025-5-13 09:52 | 顯示全部樓層
嗯,一般人很少會在中斷里面用放延時函數(shù)的,像你這種直接在中斷里面放4個delay_ms(500)加一個delay_ms(100),更加少見,大概就像,你正常情況下每秒鐘必須呼吸一次(中斷需要要循環(huán)訪問,后臺自動控制決定的),然后你訓(xùn)練拳法,沒呼吸一次要打300拳法(你一個中斷占用了2秒多),你不管你的肺抗不扛得住,憋暈過去也要打完300拳法(你也不管其他中斷會不會沖突是吧,),打完拳你也不呼氣(按鍵中斷的標(biāo)簽去除了,但是按鍵彈起來了嗎)
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);
}
回復(fù)

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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;                                        //清空當(dāng)前計數(shù)值
        SysTick->CTRL = 0x00000005;                                //設(shè)置時鐘源為HCLK,啟動定時器
        while(!(SysTick->CTRL & 0x00010000));        //等待計數(shù)到0
        SysTick->CTRL = 0x00000004;                                //關(guān)閉定時器
}
打個斷點仿真下就看到了,中斷運行后卡到了deay函數(shù)等待計數(shù)到0。感覺是在main中delay時,進(jìn)入中斷,中斷delay后閉定時器,中斷完回到main中的delay,這時的計數(shù)器已經(jīng)關(guān)閉了。卡到“while(!(SysTick->CTRL & 0x00010000));”這一句。在while中添加個檢測計數(shù)器是否關(guān)閉,如果關(guān)閉的,打開計時器。

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

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

使用道具 舉報

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)閉了計時器,導(dǎo)致主函數(shù)里的DELAY也關(guān)閉了。
      所以如果在中斷函數(shù)里需要延時,最好是用定時計數(shù)器重新寫一個。
回復(fù)

使用道具 舉報

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

使用道具 舉報

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秒。現(xiàn)在我知道,不能在中斷中處理這么多任務(wù),只能在主程序里處理。那么,該怎么通知主程序呢?是讓主程序不斷在while循環(huán)里掃描,看中斷標(biāo)志位是否為1嗎?那樣的話,是不是都可以不用外部中斷了,直接在主程序里掃描那個IO口的電平判斷按鈕是否按下即可。
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2025-5-15 10:04 | 顯示全部樓層
紅花無常 發(fā)表于 2025-5-14 21:35
好的,謝謝。原則我明白了,具體是通過何種方式實現(xiàn)呢?比如,在觸發(fā)中斷后,有一連串的操作,耗時6-7秒 ...

假設(shè)你是按鍵觸發(fā),那么好,你全聲明一個全局變量
u8 key_f = 0;//這個變量就是用來通知主程序的
在中斷程序中

EXTI9-5中斷
{
  key_f = 1;
}

主程序中
main()
{
   if(key_f)
   {
      key_f = 0;
      按鍵處理相關(guān)代碼;
    }
}
key_f 在中斷記錄, 在主程序中清除,這是提供一個思路,原理就大概是這么個原理
回復(fù)

使用道具 舉報

ID:205485 發(fā)表于 2025-5-15 13:52 | 顯示全部樓層
Y_G_G 發(fā)表于 2025-5-15 10:04
假設(shè)你是按鍵觸發(fā),那么好,你全聲明一個全局變量
u8 key_f = 0;//這個變量就是用來通知主程序的
在中斷 ...

     您說的這個意思我能明白,只是,如果這樣的話,是不是中斷都可以不要了,像下面這樣就行了。我一直沒搞清楚的就是這個。
main()
{
   if(KEY按下)
   {
      按鍵處理相關(guān)代碼;
    }
}
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2025-5-15 16:23 | 顯示全部樓層
紅花無常 發(fā)表于 2025-5-15 13:52
您說的這個意思我能明白,只是,如果這樣的話,是不是中斷都可以不要了,像下面這樣就行了。我一直 ...

對于按鍵中斷,并不是絕對需要的,可以不用中斷,直接在主程序中掃描按鍵就可以了
但有時候是要中斷的,比如按鍵級別要求要高的,或者是按鍵要喚醒單片機(jī)的,這個時候就會用到中斷
而且,按鍵不是中斷還是在主程序中掃描,都是需要去抖動和識別按鍵的
不然的話,你這個
if(KEY按下)
   {
      按鍵處理相關(guān)代碼;
    }
如果按鍵一直按著,程序就一直在執(zhí)行
回復(fù)

使用道具 舉報

ID:205485 發(fā)表于 2025-5-16 13:48 | 顯示全部樓層
Y_G_G 發(fā)表于 2025-5-15 16:23
對于按鍵中斷,并不是絕對需要的,可以不用中斷,直接在主程序中掃描按鍵就可以了
但有時候是要中斷的,比如 ...

謝謝,學(xué)到了很多知識
回復(fù)

使用道具 舉報

ID:1152844 發(fā)表于 2025-6-5 16:24 | 顯示全部樓層
按鍵消抖了嗎
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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