久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: STM32單片機外部中斷結束后的返回問題 [打印本頁]

作者: 紅花無常    時間: 2025-5-12 23:46
標題: STM32單片機外部中斷結束后的返回問題
     大家好!我最近在學習STM32的外部中斷,遇到一個問題,在這里請教大家。因為程序簡單,附件里也有程序,所以就不畫圖了,大致描述一下:
1,用STM32F103C8T6的最小系統寫了一個最簡單的程序,主程序里就一個while(1),里面是讓一個LED燈循環閃爍。
2,在主程序基礎上,增加了一個外部中斷,按下按鍵則進入中斷,在中斷里LED燈閃爍兩次。
      程序正常運行,上電LED閃爍,按下按鍵可以進入中斷,也能觀察到燈閃爍兩次。但是,中斷執行完后,程序并不是返回while(1)里讓燈繼續閃爍,而是停止了(燈熄滅狀態)。再次按下按鍵,仍然可以進入中斷,仍然不返回主程序的while(1)。
     初學者,水平很差,我想問一下,中斷執行完畢后,不是返回主程序繼續執行中斷前的程序嗎?是我的理解不對嗎?
     中斷里已經清除了標志位的。附件里是程序,文件BUZZER是燈,METAL是按鍵及中斷。謝謝。

外部中斷.7z

183.82 KB, 下載次數: 0


作者: 紅花無常    時間: 2025-5-13 08:39








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


作者: 123156fsadf    時間: 2025-5-13 08:46
中斷里面不要放軟件延時函數,另外中斷里面的代碼一定要精簡,最好控制在100us以內
作者: GlenXu    時間: 2025-5-13 09:33
應該是中斷級別的我問題,高級中斷里調用了更高級中斷DELAY(SYSTICK).
作者: 黃youhui    時間: 2025-5-13 09:52
嗯,一般人很少會在中斷里面用放延時函數的,像你這種直接在中斷里面放4個delay_ms(500)加一個delay_ms(100),更加少見,大概就像,你正常情況下每秒鐘必須呼吸一次(中斷需要要循環訪問,后臺自動控制決定的),然后你訓練拳法,沒呼吸一次要打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);
}
作者: 紅花無常    時間: 2025-5-13 10:40
謝謝大家,我剛才把延時全部調整成了1毫秒,問題依然存在。估計是前面那個朋友說的,是延時函數的優先級問題。
作者: 紅花無常    時間: 2025-5-13 12:59
中斷里只要有延時函數,不論長短(即使幾微秒),都會卡死;注釋掉延時函數,就好了。
作者: lose2836    時間: 2025-5-14 00:06
紅花無常 發表于 2025-5-13 10:40
謝謝大家,我剛才把延時全部調整成了1毫秒,問題依然存在。估計是前面那個朋友說的,是延時函數的優先級問 ...

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

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

              SysTick->CTRL = 0x00000005;                                //設置時鐘源為HCLK,啟動定時器                       
                }
                       
                       

作者: 紅花無常    時間: 2025-5-14 12:02
lose2836 發表于 2025-5-14 00:06
void Delay_us(uint32_t xus)
{
        SysTick->LOAD = 72 * xus;                                //設置定時器重裝值

      謝謝!看來問題應該就是出在這里。主函數里有DELAY,主函數正在執行DELAY時,發生了中斷,中斷函數里也有DELAY,中斷函數里執行完DELAY后,關閉了計時器,導致主函數里的DELAY也關閉了。
      所以如果在中斷函數里需要延時,最好是用定時計數器重新寫一個。
作者: Y_G_G    時間: 2025-5-14 12:39
1,中斷中不要做太多的任務,delay這種延時更加不要加,不管是按鍵也好,ADC也好,還是其它的什么,中斷事件只要觸發某個事件的標志就可以了,再在主函數中根據對應的標志進行處理
比如ADC,串口之類的,就只管把數據保存就可以了,不要在中斷中處理,當然,STM32有DMA,那是以后的事了
2,長時間延時,可以用定時器來進行,類似于SysTick的方式,不要死等,讓單片機500mS什么事都不做,這不是一個好習慣
作者: 紅花無常    時間: 2025-5-14 21:35
Y_G_G 發表于 2025-5-14 12:39
1,中斷中不要做太多的任務,delay這種延時更加不要加,不管是按鍵也好,ADC也好,還是其它的什么,中斷事件只要 ...

好的,謝謝。原則我明白了,具體是通過何種方式實現呢?比如,在觸發中斷后,有一連串的操作,耗時6-7秒。現在我知道,不能在中斷中處理這么多任務,只能在主程序里處理。那么,該怎么通知主程序呢?是讓主程序不斷在while循環里掃描,看中斷標志位是否為1嗎?那樣的話,是不是都可以不用外部中斷了,直接在主程序里掃描那個IO口的電平判斷按鈕是否按下即可。
作者: Y_G_G    時間: 2025-5-15 10:04
紅花無常 發表于 2025-5-14 21:35
好的,謝謝。原則我明白了,具體是通過何種方式實現呢?比如,在觸發中斷后,有一連串的操作,耗時6-7秒 ...

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

EXTI9-5中斷
{
  key_f = 1;
}

主程序中
main()
{
   if(key_f)
   {
      key_f = 0;
      按鍵處理相關代碼;
    }
}
key_f 在中斷記錄, 在主程序中清除,這是提供一個思路,原理就大概是這么個原理
作者: 紅花無常    時間: 2025-5-15 13:52
Y_G_G 發表于 2025-5-15 10:04
假設你是按鍵觸發,那么好,你全聲明一個全局變量
u8 key_f = 0;//這個變量就是用來通知主程序的
在中斷 ...

     您說的這個意思我能明白,只是,如果這樣的話,是不是中斷都可以不要了,像下面這樣就行了。我一直沒搞清楚的就是這個。
main()
{
   if(KEY按下)
   {
      按鍵處理相關代碼;
    }
}
作者: Y_G_G    時間: 2025-5-15 16:23
紅花無常 發表于 2025-5-15 13:52
您說的這個意思我能明白,只是,如果這樣的話,是不是中斷都可以不要了,像下面這樣就行了。我一直 ...

對于按鍵中斷,并不是絕對需要的,可以不用中斷,直接在主程序中掃描按鍵就可以了
但有時候是要中斷的,比如按鍵級別要求要高的,或者是按鍵要喚醒單片機的,這個時候就會用到中斷
而且,按鍵不是中斷還是在主程序中掃描,都是需要去抖動和識別按鍵的
不然的話,你這個
if(KEY按下)
   {
      按鍵處理相關代碼;
    }
如果按鍵一直按著,程序就一直在執行
作者: 紅花無常    時間: 2025-5-16 13:48
Y_G_G 發表于 2025-5-15 16:23
對于按鍵中斷,并不是絕對需要的,可以不用中斷,直接在主程序中掃描按鍵就可以了
但有時候是要中斷的,比如 ...

謝謝,學到了很多知識
作者: MMma190    時間: 2025-6-5 16:24
按鍵消抖了嗎




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 国产日韩欧美亚洲 | 久国产| 三年中文在线看免费观看 | 日本三级大片 | 一区二区三区黄色 | 中文字幕一区二区三区在线观看 | 中文字幕在线视频观看 | 日韩三级在线播放 | 女人一级一片30分 | 午夜久久久久久 | 伊人久久网站 | 欧美区一区二 | 中文字幕在线播放视频 | av在线资源网 | 性久久久久久久 | 欧洲一级片 | 欧美极品一区 | 成人久久视频 | 伊人成人在线视频 | a级片在线观看 | 午夜视频福利 | 午夜精品国产精品大乳美女 | 成人b站| 成人免费黄色大片 | 国产剧情在线 | 欧美成人小视频 | 免费日韩视频 | 欧美香蕉视频 | 欧美日韩一区在线 | 全部免费毛片在线播放高潮 | 中文字幕在线观看免费 | 在线成人免费视频 | 亚洲高清视频在线观看 | 国产高清一区二区 | 日本黄色免费视频 | 激情婷婷综合 | 97在线免费视频 | 国产麻豆xxxvideo实拍 | 精品在线免费视频 | 国产三级在线观看视频 | 欧美资源在线 |