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

QQ登錄

只需一步,快速開始

搜索
查看: 2877|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

C語言函數(shù)編譯時(shí)一直報(bào)重復(fù)?WARNING L15: MULTIPLE CALL TO SEGMENT

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
上代碼:void Timer1Init(void)                //20毫秒@12.000MHz
{
        TMOD &= 0x0F;        //設(shè)置定時(shí)器模式
        TMOD |= 0x10;        //設(shè)置定時(shí)器模式
        TL1 = 0xE0;                //設(shè)置定時(shí)初值
        TH1 = 0xB1;                //設(shè)置定時(shí)初值
        TF1 = 0;                //清除TF1標(biāo)志
        TR1 = 1;                //定時(shí)器1開始計(jì)時(shí)
        ET1=1;                        //允許定時(shí)器申請(qǐng)中斷
        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();//在這里調(diào)用又沒事??????這是什么邏輯????
        }
}


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




編譯器報(bào)錯(cuò)為    *** WARNING L15: MULTIPLE CALL TO SEGMENT


請(qǐng)教論壇師傅
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:161164 發(fā)表于 2021-9-5 14:45 | 只看該作者
因?yàn)槟愕膬蓚(gè)函數(shù)中會(huì)同時(shí)呼叫Teset()                               (PS: 不是Test嗎?從上一個(gè)貼子已出現(xiàn)這個(gè)錯(cuò)字了,還沒改過來?)
有機(jī)會(huì)在運(yùn)行Teset2()中的Teset()時(shí)剛好進(jìn)入中斷
于是又呼叫Teset()

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

當(dāng)然,這只是有機(jī)會(huì)發(fā)生,
所以他只是一個(gè)警告(Waring)而不是錯(cuò)誤(Error)
不影響編譯,不理會(huì)也可以運(yùn)行
但編程時(shí)最好不要有太多嵌套

回復(fù)

使用道具 舉報(bào)

板凳
ID:232366 發(fā)表于 2021-9-5 14:50 | 只看該作者
lkc8210 發(fā)表于 2021-9-5 14:45
因?yàn)槟愕膬蓚(gè)函數(shù)中會(huì)同時(shí)呼叫Teset()                               (PS: 不是Test嗎?從上一個(gè)貼子已出 ...

真的是太感謝您了。。。!我前面一直在想是不是我程序框架搭錯(cuò)了想了很久   沒想到給您一語道破。。!太感謝了
回復(fù)

使用道具 舉報(bào)

地板
ID:232366 發(fā)表于 2021-9-5 14:53 | 只看該作者
lkc8210 發(fā)表于 2021-9-5 14:45
因?yàn)槟愕膬蓚(gè)函數(shù)中會(huì)同時(shí)呼叫Teset()                               (PS: 不是Test嗎?從上一個(gè)貼子已出 ...

不好意思敲錯(cuò)錯(cuò)了我一直沒發(fā)現(xiàn)呢。。!尷尬
回復(fù)

使用道具 舉報(bào)

5#
ID:232366 發(fā)表于 2021-9-5 15:03 | 只看該作者
lkc8210 發(fā)表于 2021-9-5 14:45
因?yàn)槟愕膬蓚(gè)函數(shù)中會(huì)同時(shí)呼叫Teset()                               (PS: 不是Test嗎?從上一個(gè)貼子已出 ...

還是要感謝您耐心指出我的問題并作出修改
回復(fù)

使用道具 舉報(bào)

6#
ID:624769 發(fā)表于 2021-9-5 16:54 | 只看該作者
中斷要調(diào)用的子函數(shù),必須單獨(dú)寫,不然別的程序調(diào)用中,中斷時(shí)又調(diào)用,會(huì)有 重入錯(cuò)誤。
你要是實(shí)在要用一樣的子函數(shù),就原封不動(dòng)照抄一編,重新命名一個(gè)名字給中斷單獨(dú)用。
建議養(yǎng)成習(xí)慣,中斷不調(diào)用任何子函數(shù)。要么直接寫中斷里,要么精簡中斷,中斷只作標(biāo)志,讓主程序周期執(zhí)行。
回復(fù)

使用道具 舉報(bào)

7#
ID:960726 發(fā)表于 2021-9-5 23:11 | 只看該作者
主程序和中斷服務(wù)程序通常不允許同時(shí)調(diào)用同一個(gè)函數(shù),除非函數(shù)為可重入函數(shù)。你的程序思路沒有錯(cuò),但是編譯系統(tǒng)邏輯上會(huì)混亂,想象一下,主程序正在執(zhí)行函數(shù)A,突然中斷了,再次調(diào)用這個(gè)函數(shù),當(dāng)中斷返回時(shí)無法回到斷點(diǎn)了。建議你單獨(dú)寫主程序中的Teset2(),因?yàn)槌跏蓟恍枰獔?zhí)行一次。
回復(fù)

使用道具 舉報(bào)

8#
ID:883242 發(fā)表于 2021-9-5 23:30 | 只看該作者
樓主的寫法在正規(guī)的c語言編譯器里面是正確無誤的,不管是主循環(huán)還是中斷調(diào)用Teset()都是在堆棧上臨時(shí)生成局部變量空間,退出后堆棧上面的局部變量失效,可以參閱用c語言寫的《數(shù)據(jù)結(jié)構(gòu)》關(guān)于遞歸那一章。

但是在大多數(shù)8位單片機(jī)上面使用標(biāo)準(zhǔn)c語言做法,因?yàn)?位單片機(jī)設(shè)計(jì)之初就沒想過用什么高級(jí)語言,相關(guān)指令都沒有,所以代碼會(huì)變得很長,運(yùn)行時(shí)間也會(huì)變長,時(shí)間和空間都要付出相當(dāng)大的代價(jià)。所以Keil C51之類的編譯器就違反了標(biāo)準(zhǔn)c語言的做法,在RAM內(nèi)部靜態(tài)分配變量,比如Teset()局部變量地址0x20(隨手舉個(gè)栗子),主函數(shù)調(diào)用Teset(),發(fā)生中斷,中斷調(diào)用Teset(),0x20局部變量的值就被修改了,中斷返回后繼續(xù)執(zhí)行主函數(shù)調(diào)用的Teset(),就會(huì)因?yàn)榫植孔兞勘恍薷亩l(fā)生異常。
回復(fù)

使用道具 舉報(bào)

9#
ID:232366 發(fā)表于 2021-9-6 07:23 來自手機(jī) | 只看該作者
Hephaestus 發(fā)表于 2021-9-5 23:30
樓主的寫法在正規(guī)的c語言編譯器里面是正確無誤的,不管是主循環(huán)還是中斷調(diào)用Teset()都是在堆棧上臨時(shí)生成局 ...

原來如此!感謝您回復(fù)個(gè)耐心回答。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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