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

QQ登錄

只需一步,快速開(kāi)始

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

求助:中斷函數(shù)問(wèn)題

[復(fù)制鏈接]
ID:1059305 發(fā)表于 2022-12-28 14:30 | 顯示全部樓層 |閱讀模式
目的:?jiǎn)纹瑱C(jī)上電后,顯示流水燈,按下按鍵后小燈全亮,然后返回主函數(shù),繼續(xù)顯示流水燈。
目前問(wèn)題:按下按鍵后,小燈全亮,但松開(kāi)按鍵后小燈還是保持全亮,沒(méi)有恢復(fù)中斷前的狀態(tài)。
請(qǐng)問(wèn)這是什么原因?qū)е,以下是代碼
#include <reg52.h>
#include <intrins.h>
#define LED P0

sbit K1=P3^2;
int a;

void delay(ms)
{
        int i;
        while(ms--)
        {
                for (i=0;i<100;i++)
                {
                        ;
                }
        }
}

void zhongduan()
{
        EA=1;
        EX0=1;
}

void main()
{
        a=0;
        zhongduan();
        LED=0xfe;
        delay(200);
        while(1)
        {
               
                for(a=0;a<7;a++)
                {
                        LED=_crol_(LED,1);

                        delay(250);
                }
               
                for(a=0;a<7;a++)
                {
                        LED=_cror_(LED,1);

                        delay(250);
                }
      
}
}
void init0() interrupt 0
{
        if(K1==0)
        {
                delay(10);
                if(K1==0)
                {
                        LED=0x00;
                        delay(200);
                }
        }
      
}
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2022-12-28 20:17 | 顯示全部樓層
你在中斷中已經(jīng)改變LED狀態(tài)0x00,出中斷后LED沒(méi)有恢復(fù)之前狀態(tài),主函數(shù)繼續(xù)左(右)移0x00能有什么意義?

void init0() interrupt 0
{
        unsigned char num;

        if(K1==0)
        {
                delay(10);
                if(K1==0)
                {
                        num=LED;//保存當(dāng)前狀態(tài)
                        LED=0x00;
                        delay(200);
                        LED=num;//恢復(fù)之前狀態(tài)
                }
        }
}
回復(fù)

使用道具 舉報(bào)

ID:1056573 發(fā)表于 2022-12-29 05:30 | 顯示全部樓層
void zhongduan()函數(shù)里少了個(gè)外部中斷觸發(fā)方式IT0=1;。
回復(fù)

使用道具 舉報(bào)

ID:94031 發(fā)表于 2022-12-29 07:01 | 顯示全部樓層
中斷處理要求時(shí)間越短越好,不要在中斷里延時(shí)。
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 09:31 | 顯示全部樓層
wulin 發(fā)表于 2022-12-28 20:17
你在中斷中已經(jīng)改變LED狀態(tài)0x00,出中斷后LED沒(méi)有恢復(fù)之前狀態(tài),主函數(shù)繼續(xù)左(右)移0x00能有什么意義?
...

謝謝。。!我明白了
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 09:35 | 顯示全部樓層
ytchfp163 發(fā)表于 2022-12-29 05:30
void zhongduan()函數(shù)里少了個(gè)外部中斷觸發(fā)方式IT0=1;。

我也試過(guò)加上這個(gè)IT0=1但還是不行,按照上一樓修改代碼,可以不寫(xiě)IT0=1也可以實(shí)現(xiàn)
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 09:36 | 顯示全部樓層
xuyaqi 發(fā)表于 2022-12-29 07:01
中斷處理要求時(shí)間越短越好,不要在中斷里延時(shí)。

好的,好的下一步我試試用個(gè)定時(shí)器代替延時(shí)
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2022-12-29 13:34 來(lái)自觸屏版 | 顯示全部樓層
了解一下什么叫現(xiàn)場(chǎng)保護(hù),恢復(fù)現(xiàn)場(chǎng),學(xué)會(huì)push,pop的用法。
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 14:20 | 顯示全部樓層
188610329 發(fā)表于 2022-12-29 13:34
了解一下什么叫現(xiàn)場(chǎng)保護(hù),恢復(fù)現(xiàn)場(chǎng),學(xué)會(huì)push,pop的用法。

謝謝,我看了一下,好像了解現(xiàn)場(chǎng)保護(hù)和恢復(fù)現(xiàn)場(chǎng),但目前我對(duì)這堆?臻g的使用理解并不深,比較熟悉的就只是使用指針,但怎么釋放堆的內(nèi)存我還沒(méi)懂,目前打算學(xué)一學(xué)基礎(chǔ)知識(shí),然后做點(diǎn)小項(xiàng)目,一邊做一邊學(xué),相互印證。
回復(fù)

使用道具 舉報(bào)

ID:384109 發(fā)表于 2022-12-29 14:42 | 顯示全部樓層
需要檢測(cè)按鍵的釋放,需要一個(gè)變量來(lái)保存按鍵按下時(shí)LED的狀態(tài)
回復(fù)

使用道具 舉報(bào)

ID:77589 發(fā)表于 2022-12-29 15:07 | 顯示全部樓層
中斷響應(yīng)后,執(zhí)行中斷響應(yīng)程序后,需要清除中斷標(biāo)志,如果沒(méi)有清除中斷標(biāo)志位,單片機(jī)就會(huì)一直重復(fù)響應(yīng)中斷,其它代碼就不會(huì)執(zhí)行。
好久沒(méi)用51單片機(jī)了,不知道說(shuō)的對(duì)不對(duì),但可以試試。
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 16:42 | 顯示全部樓層
Longan.Wang 發(fā)表于 2022-12-29 15:07
中斷響應(yīng)后,執(zhí)行中斷響應(yīng)程序后,需要清除中斷標(biāo)志,如果沒(méi)有清除中斷標(biāo)志位,單片機(jī)就會(huì)一直重復(fù)響應(yīng)中斷 ...

我剛剛試了一下,在中斷結(jié)束后清除中斷標(biāo)志位,但還是沒(méi)有恢復(fù)中斷前狀態(tài),我覺(jué)得問(wèn)題還是在2樓所說(shuō)的,在中斷時(shí)改變了LED的狀態(tài),然后沒(méi)有恢復(fù)之前的狀態(tài)。按照2樓所說(shuō)的操作,我成功實(shí)現(xiàn)中斷后LED恢復(fù)原來(lái)的狀態(tài)。這是我添加的清除中斷標(biāo)志位,不知道有沒(méi)有錯(cuò)。
  1. void init0() interrupt 0
  2. {

  3.         if(K1==0)
  4.         {
  5.                 delay(10);
  6.                 if(K1==0)
  7.                 {
  8.       LED=0x00;
  9.                         delay(200);
  10.                         IE0=0;
  11.                
  12.                 }
  13.         }
  14.        
  15. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:1059305 發(fā)表于 2022-12-29 16:44 | 顯示全部樓層
人中狼 發(fā)表于 2022-12-29 14:42
需要檢測(cè)按鍵的釋放,需要一個(gè)變量來(lái)保存按鍵按下時(shí)LED的狀態(tài)

是的,需要保存中斷前的狀態(tài),然后再恢復(fù)狀態(tài)
回復(fù)

使用道具 舉報(bào)

ID:1059578 發(fā)表于 2022-12-29 17:37 | 顯示全部樓層
不要在中斷里延時(shí)
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2022-12-30 20:52 | 顯示全部樓層
LLL2022 發(fā)表于 2022-12-29 14:20
謝謝,我看了一下,好像了解現(xiàn)場(chǎng)保護(hù)和恢復(fù)現(xiàn)場(chǎng),但目前我對(duì)這堆?臻g的使用理解并不深,比較熟悉的就只 ...

以你的代碼為例, 你要在主函數(shù)中 不斷 改變 "LED"    而中斷中又要 “臨時(shí)的” 改變“LED”,而退出中斷后又希望恢復(fù)“LED”本來(lái)的內(nèi)容。雖然不建議這種中斷中 Delay 的寫(xiě)法,但是,先不說(shuō)這個(gè)。 這其中的“LED” 就是你需要保護(hù)的現(xiàn)場(chǎng)。這個(gè)時(shí)候一般需要用到  入棧 和 出棧 比如:

void init0() interrupt 0
{
        _push_(LED);          //入棧
        if(K1==0)
        {
                delay(10);
                if(K1==0)
                {
                        LED=0x00;
                        delay(200);
                }
        }
        _pop_(LED);          //出棧      
}

當(dāng)然,沙發(fā)的那個(gè)方法也可以,但是,如果有中斷嵌套,多個(gè)涉及到 相同的“現(xiàn)場(chǎng)”,就不如 出入棧來(lái)的穩(wěn)妥了。


回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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