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

標題: C語言函數編譯時一直報重復?WARNING L15: MULTIPLE CALL TO SEGMENT [打印本頁]

作者: SHANWAZI    時間: 2021-9-5 12:21
標題: C語言函數編譯時一直報重復?WARNING L15: MULTIPLE CALL TO SEGMENT
上代碼:void Timer1Init(void)                //20毫秒@12.000MHz
{
        TMOD &= 0x0F;        //設置定時器模式
        TMOD |= 0x10;        //設置定時器模式
        TL1 = 0xE0;                //設置定時初值
        TH1 = 0xB1;                //設置定時初值
        TF1 = 0;                //清除TF1標志
        TR1 = 1;                //定時器1開始計時
        ET1=1;                        //允許定時器申請中斷
        EA=1;                        //打開總中斷
}





bit Teset()
{
        bit ack;
        
        ack=0;
        
        return ack;
}

bit Teset2()
{
        bit ack;
        
        ack=Teset();
        if(ack==0)
        {
               
        }
        return ack;
}


void Drive()
{
        static xdata uint16 Count=0;
        
        bit ack;
        
        Count++;
        if(Count>=100)
        {
                Count=0;
                ack=Teset();
                if(ack==1)
                {
                        
                }
                Teset2();
        }
}


void main(void)
{        
        Timer1Init();                                        //20毫秒@12.000MHz        
        delay(100);
        Teset2();
        while(1)
        {
                 //Drive();//在這里調用又沒事??????這是什么邏輯????
        }
}


void Timer1(void) interrupt 3//20毫秒@12.000MHz
{
        TR1=0;
        Drive();//在這里中斷這里調用就報錯????
        TL1 = 0xE0;                //設置定時初值
        TH1 = 0xB1;                //設置定時初值
        TR1=1;
}




編譯器報錯為    *** WARNING L15: MULTIPLE CALL TO SEGMENT


請教論壇師傅

作者: lkc8210    時間: 2021-9-5 14:45
因為你的兩個函數中會同時呼叫Teset()                               (PS: 不是Test嗎?從上一個貼子已出現這個錯字了,還沒改過來?)
有機會在運行Teset2()中的Teset()時剛好進入中斷
于是又呼叫Teset()

如果放進while(1)里就不會有這種情況

當然,這只是有機會發生,
所以他只是一個警告(Waring)而不是錯誤(Error)
不影響編譯,不理會也可以運行
但編程時最好不要有太多嵌套


作者: SHANWAZI    時間: 2021-9-5 14:50
lkc8210 發表于 2021-9-5 14:45
因為你的兩個函數中會同時呼叫Teset()                               (PS: 不是Test嗎?從上一個貼子已出 ...

真的是太感謝您了!!!!!我前面一直在想是不是我程序框架搭錯了想了很久   沒想到給您一語道破!!!!太感謝了
作者: SHANWAZI    時間: 2021-9-5 14:53
lkc8210 發表于 2021-9-5 14:45
因為你的兩個函數中會同時呼叫Teset()                               (PS: 不是Test嗎?從上一個貼子已出 ...

不好意思敲錯錯了我一直沒發現呢!!!!尷尬
作者: SHANWAZI    時間: 2021-9-5 15:03
lkc8210 發表于 2021-9-5 14:45
因為你的兩個函數中會同時呼叫Teset()                               (PS: 不是Test嗎?從上一個貼子已出 ...

還是要感謝您耐心指出我的問題并作出修改
作者: 188610329    時間: 2021-9-5 16:54
中斷要調用的子函數,必須單獨寫,不然別的程序調用中,中斷時又調用,會有 重入錯誤。
你要是實在要用一樣的子函數,就原封不動照抄一編,重新命名一個名字給中斷單獨用。
建議養成習慣,中斷不調用任何子函數。要么直接寫中斷里,要么精簡中斷,中斷只作標志,讓主程序周期執行。
作者: seuww    時間: 2021-9-5 23:11
主程序和中斷服務程序通常不允許同時調用同一個函數,除非函數為可重入函數。你的程序思路沒有錯,但是編譯系統邏輯上會混亂,想象一下,主程序正在執行函數A,突然中斷了,再次調用這個函數,當中斷返回時無法回到斷點了。建議你單獨寫主程序中的Teset2(),因為初始化只需要執行一次。
作者: Hephaestus    時間: 2021-9-5 23:30
樓主的寫法在正規的c語言編譯器里面是正確無誤的,不管是主循環還是中斷調用Teset()都是在堆棧上臨時生成局部變量空間,退出后堆棧上面的局部變量失效,可以參閱用c語言寫的《數據結構》關于遞歸那一章。

但是在大多數8位單片機上面使用標準c語言做法,因為8位單片機設計之初就沒想過用什么高級語言,相關指令都沒有,所以代碼會變得很長,運行時間也會變長,時間和空間都要付出相當大的代價。所以Keil C51之類的編譯器就違反了標準c語言的做法,在RAM內部靜態分配變量,比如Teset()局部變量地址0x20(隨手舉個栗子),主函數調用Teset(),發生中斷,中斷調用Teset(),0x20局部變量的值就被修改了,中斷返回后繼續執行主函數調用的Teset(),就會因為局部變量被修改而發生異常。
作者: SHANWAZI    時間: 2021-9-6 07:23
Hephaestus 發表于 2021-9-5 23:30
樓主的寫法在正規的c語言編譯器里面是正確無誤的,不管是主循環還是中斷調用Teset()都是在堆棧上臨時生成局 ...

原來如此!感謝您回復個耐心回答。




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1