資源描述:
《KEIL C51使用技巧》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、函數(shù)的遞歸調(diào)用和再入函數(shù)函數(shù)類型函數(shù)名(形參表)[reentrant]再入函數(shù)可被遞歸調(diào)用,無論何時(shí),包括中斷服務(wù)函數(shù)在內(nèi)的任何函數(shù)都可調(diào)用再入函數(shù)。與非再入函數(shù)的參數(shù)傳遞和局部變量的存儲(chǔ)分配方式不同,Cx51編譯器為再入函數(shù)生成一個(gè)模擬棧,通過其來完成參數(shù)傳遞和存放局部變量。模擬棧所在的存儲(chǔ)器空間根據(jù)再入函數(shù)存儲(chǔ)器模式的不同,可以是DATA、PDATA、XDATA存儲(chǔ)器空間。當(dāng)程序中包含有多種存儲(chǔ)器模式的再入函數(shù)時(shí),編譯器為每種模式單獨(dú)建立一個(gè)模擬棧并獨(dú)立管理各自的棧指針。對(duì)于再入函數(shù)有如下規(guī)定:(1)再入函數(shù)不能傳送bit類型的參數(shù),也不能定義一個(gè)局部位變量,再入函
2、數(shù)不能包括位操作和8051系列單片機(jī)的可位尋址區(qū)(2)與PL/M51兼容的函數(shù)不能具有reentrant屬性,也不能調(diào)用再入函數(shù)(3)編譯時(shí)存儲(chǔ)器模式基礎(chǔ)上為再入函數(shù)在內(nèi)部或外部存儲(chǔ)器中建立一個(gè)模擬堆棧區(qū),稱為再入棧。在small模擬下再入棧位于idata區(qū),在compact模式下再入棧位于pdaa區(qū),在large模式下再入棧位于xdata區(qū)。再入函數(shù)的局部變量及參數(shù)都被放入再入棧中,從而使再入函數(shù)可進(jìn)行遞歸調(diào)用。而非再入函數(shù)的局部變量被放在再入棧外的暫存區(qū)內(nèi),如對(duì)其進(jìn)行遞歸調(diào)用,則上次調(diào)用時(shí)使用的局部變量數(shù)據(jù)將被覆蓋。(4)在同意個(gè)程序中可定義或使用不同存儲(chǔ)器模式的再
3、入函數(shù),任意模式的再入函數(shù)不能調(diào)用不同模式的再入函數(shù),但可任意調(diào)用非再入函數(shù)。(5)在參數(shù)的傳遞上,實(shí)際參數(shù)可傳遞給間接調(diào)用的再入函數(shù)。無再入屬性的間接調(diào)用函數(shù)不能包含調(diào)用參數(shù),但可以使用定義的全局變量來進(jìn)行參數(shù)傳遞。采用函數(shù)遞歸調(diào)用可使程序結(jié)構(gòu)緊湊,但要求采用再入函數(shù),以便利用再入棧來保存有關(guān)的局部變量數(shù)據(jù),因此要占用較大的內(nèi)存空間。另外,遞歸調(diào)用時(shí)對(duì)函數(shù)的處理速度較慢,因此一般情況下應(yīng)盡量避免使用函數(shù)遞歸調(diào)用,定義函數(shù)時(shí)應(yīng)盡量避免使用再入屬性。8051常規(guī)棧是位于內(nèi)部數(shù)據(jù)RAM中,是向上生長型的而模擬再入棧是向下生長型的。中斷服務(wù)函數(shù)與寄存器組定義C語言中一般形式為
4、:函數(shù)類型函數(shù)名(形參表)[interruptn][usingn]Interruptn中n為中斷號(hào),取值范圍0-31,編譯器從8n+3處產(chǎn)生中斷向量一般常用的中斷向量表如下:中斷號(hào)n中斷源中斷向量8n+30外部中斷00003H1定時(shí)器0000BH2外部中斷10013H1定時(shí)器1001BH4串行口0023H8051系列單片機(jī)片內(nèi)RAM使用4個(gè)不同的工作寄存器組,每個(gè)組中有8個(gè)寄存器R0-R7擴(kuò)展關(guān)鍵字using專門用于選擇不同的工作寄存器組,n范圍0-3。若不選擇using,則由編譯器自動(dòng)選擇一個(gè)寄存器組作為絕對(duì)寄存器組訪問。注意該關(guān)鍵字后面不允許跟帶運(yùn)算符的表達(dá)式。該關(guān)
5、鍵字對(duì)函數(shù)目標(biāo)代碼的影響如下:在函數(shù)入口處將當(dāng)前工作寄存器組保護(hù)到堆棧中;指定的工作寄存器內(nèi)容不會(huì)改變;函數(shù)退出前將被保護(hù)的工作寄存器組從堆棧中恢復(fù)。使用關(guān)鍵字using要保證任何寄存器組的切換都只在仔細(xì)控制的區(qū)域中發(fā)生。帶該關(guān)鍵字的函數(shù)原則上不能返回bit類型的值。關(guān)鍵字using不允許用于外部函數(shù)。關(guān)鍵字interrupt不允許用于外部函數(shù),對(duì)中斷函數(shù)目標(biāo)代碼的影響如下:在進(jìn)入中斷函數(shù)時(shí),特殊功能寄存器ACC、B、DPH、DPL、PSW將被保存入棧若不使用關(guān)鍵字using進(jìn)行工作寄存器組切換,則將中斷函數(shù)所用到的工作寄存器都入棧保存函數(shù)退出前所有寄存器內(nèi)容出?;謴?fù)中
6、斷函數(shù)由RETI結(jié)束中斷函數(shù)編寫需遵循的原則(1)中斷函數(shù)不能進(jìn)行參數(shù)傳遞,否則編譯報(bào)錯(cuò)(2)中斷函數(shù)沒有返回值,建議定義為void類型(3)任何情況下都不能直接調(diào)用中斷函數(shù),否則編譯錯(cuò)誤(4)若中斷函數(shù)調(diào)用了其他函數(shù),則被調(diào)用函數(shù)使用的寄存器必須和中斷函數(shù)相同,由于中斷函數(shù)不可預(yù)測(cè),中斷函數(shù)對(duì)其他函數(shù)的調(diào)用有可能形成遞歸調(diào)用,需要時(shí),可將被中斷函數(shù)調(diào)用的其他函數(shù)定義成再入函數(shù)(5)KEILCx51編譯器從絕對(duì)地址8n+3處產(chǎn)生一個(gè)中斷向量,該向量包含一個(gè)到中斷函數(shù)入口地址的絕對(duì)跳轉(zhuǎn),在對(duì)源程序編譯時(shí),可用編譯控制命令NOINTVECTOR抑制中斷向量的產(chǎn)生,從而使用戶
7、有能力從獨(dú)立的匯編程序模塊中提供中斷向量。函數(shù)變量的存儲(chǔ)方式C語言中有四種存儲(chǔ)種類:自動(dòng)變量(auto):默認(rèn),也可省略申明。當(dāng)函數(shù)調(diào)用時(shí)存在,退出函數(shù)則消失。外部變量(extern)靜態(tài)變量(static):分局部靜態(tài)變量和全局靜態(tài)變量局部靜態(tài)變量:只能在定義它的函數(shù)中進(jìn)行訪問,退出函數(shù)后,該值依舊存在,但不能訪問。全局靜態(tài)變量:在函數(shù)外部定義,作用防衛(wèi)從它的定義點(diǎn)開始,直到程序結(jié)束。當(dāng)程序由多個(gè)模塊文件組成時(shí),該變量始終存在,但只能在被定義的模塊文件中被訪問,該數(shù)值能被該模塊文件中所有函數(shù)共享,退出該文件后,雖然變量值依舊存在,但不能