Keil使用中的若干問題)

來源:互聯網
上載者:User

一、混合編程

1、模組內介面:
使用如下標誌符:
#pragma asm
彙編語句
#pragma endasm
注意:如果在c51程式中使用了組合語言,注意在keil編譯器中需要啟用Properties中的“Generate Assembler SRC File” 和“Assembler SRC File ”兩個選項
來個執行個體吧:
#i nclude
void main(void)
{
P2=1;
#pragma asm
    MOV R7,#10
DEL:MOV R6,#20
    DJNZ R6,$
    DJNZ R7,DEL
#pragma endasm
P2=0;
}
另:
1、把"xx.c"加入工程中,右擊"xx.c"選擇“options for file"xx.c" 選擇“Generate Assembler SRC File”和“Assemble SRC File”打上黑勾有效;
2、根據選擇的編譯模式,把相應的庫檔案象加"xx.c"一樣加入工程中並放在"xx.c"下面,如smail模式下選"keil\c51\lib\c51s.lib"加入工程中,如果要進行浮點運算把"keil\c51\lib\c51fpl.lib"也加入工程中。
在 Keil 安裝目錄下的 \C51\LIB\ 目錄的LIB 檔案如下:
C51S.LIB - 沒有浮點運算的 Small model
C51C.LIB - 沒有浮點運算的 Compact model
C51L.LIB - 沒有浮點運算的 Large model
C51FPS.LIB - 帶浮點運算的 Small model
C51FPC.LIB - 帶浮點運算的 Compact model
C51FPL.LIB - 帶浮點運算的 Large model
3、在"xx.c"標頭檔中加入最佳化:比如#pragma OT(4,speed)
4、在"xx.c"中加入彙編代碼
                             #pragma ASM
                             ;Assembler Code Here
                             #pragma ENDASM
5、編譯產生xx.hex
注意:
      沒有做第一步會有如下警告:'asm/endasm' requires src-control to be active
      沒有做第二步會有如下警告:UNRESOLVED EXTERNAL SYMBOL;
                                REFERENCE MADE TO UNRESOLVED EXTERNAL等
      沒有做第三步會有如下警告:UNDEFINED SYMBOL (PASS-2) 


二、中斷使用

interrupt   xx   using   y
跟在interrupt   後面的xx   值得是中斷號,就是說這個函數對應第幾個中斷連接埠,一般在51中
0   外部中斷0   
1   定時器0
2   外部中斷1
3   定時器1
4   串列中斷
其它的根據相應的單片機有自己的含義,實際上c在編譯的時候就是把你這個函數的入口地址放到這個對應中斷的跳轉地址 。 using   y   這個y時說這個中斷函數使用的那個寄存器組就是51裡面一般有4個   r0   --   r7寄存器,如果你的終端函數和別的程式用的不是同一個寄存器組則進入中斷的時候就不會將寄存器組壓入堆棧返回時也不會彈出來節省代碼和時間。 


三、關於reentrant的使用方法及問題原因分析

雲清燕 發表於 2006-11-15 21:27:00
我在程式中出現了如下警告:
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?_CRCDATA?PANEL_DISP
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?ANALOGALLBECKON?PANEL_DISP
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?SWITCHALLBECKON?PANEL_DISP
    CALLER1: ?C_C51STARTUP
    CALLER2: ?PR?UART_RECV?PANEL_DISP///////////////////該警告表示連接器發現有一個函數可能會被主函數和一個中斷服務程式(或者調用中斷服務程式的函數)同時調用,
或者同時被多個中斷服務程式調用。
      出現這種問題的原因之一是這個函數是不可重新進入性函數,當該函數運行時它可能會被一個中斷打斷,從而使得結果發生變化
並可能會引起一些變數形式的衝突(即引起函數內一些資料的丟失,可重新進入性函數在任何時候都可以被ISR打斷,一段時間後又可以
運行,但是相應資料不會丟失)。
      原因之二是用於局部變數和變數(暫且這樣翻譯,arguments,[自變數,變元一數值,用於確定程式或子程式的值])的記憶體區被其他函數的記憶體區所覆蓋,如果該函數被中斷,則它的記憶體區就會
被使用,這將導致其他函數的記憶體衝突。
      例如,第一個警告中函數WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51被定義,它被一個中斷服務程式或者一個調用了中斷
服務程式的函數調用了,調用它的函數是VSYNC_INTERRUPT,在MAIN.C中。
解決方案:
      如果你確定兩個函數決不會在同一時間執行(該函數被主程式調用並且中斷被禁止),並且該函數不佔用記憶體(假設只使用寄存器),
則你可以完全忽略這種警告。
      如果該函數佔用了記憶體,則應該使用連接器(linker)OVERLAY指令將函數從覆蓋分析(overlay
analysis)中除去,例如:
OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
     上面的指令防止了該函數使用的記憶體區被其他函數覆蓋。如果該函數中調用了其他函數,而這些被調用在程式中其他地方也被調用,
你可能會需要也將這些函數排除在覆蓋分析(overlay analysis)之外。這種OVERLAY指令能使編譯器除去上述警告資訊。
     如果函數可以在其執行時被調用,則情況會變得更複雜一些。這時可以採用以下幾種方法:
1.主程式調用該函數時禁止中斷,可以在該函數被調用時用#pragma disable語句來實現禁止中斷的目的。必須使用OVERLAY指令將該函數
從覆蓋分析中除去。
2.複製兩份該函數的代碼,一份到主程式中,另一份複製到中斷服務程式中。
3.將該函數設為重入型。例如:
void myfunc(void) reentrant {
...
}///////////////////////
我的程式編譯出來就這3個警告,但是程式可以正常下載運行。但是我覺得有這些警告會使程式存在bug。從字面上看是它的意思是我程式中接受函數UART_RECV()多調用了analogAllBeckon()、switchAllBeckon()。
因為51的普通函數是不可重新進入的,變數放在固定的地址,兩個函數同時運行時,就會修改同一個變數,從而導致結果錯誤。於是我在analogAllBeckon()、switchAllBeckon()函數後面加了void analogAllBeckon()reentrant{//All Analog data beckon使程式消除了警告。這種方法是表明函數是可被多哥任務調用而不修改函數裡邊的變數值,以此來實現函數的重入性。
關於reentrant的使用keil的官方論壇上有詳細的討論.
Andy Neil(官方工程師)建議
"Are you sure that you really need to make everything reentrant?...A reading of the Keil app notes & knowledgebase articles on this subject showed that it was not necessary. "
由於每一次調用被reentrant聲明的函數都要把函數的參數和內部變數壓棧,所以很容易使堆棧區溢出,S52隻有256Bytes的data段,一個簡單的函數如果有一個參數三個內部變數,則需要壓棧4位元組以上,這還不包括函數呼叫堆疊.reentrant其實並不是適合低端的單片機,keil論壇上有人說對於那些有KB以上RAM的單片機reentrant才適合.

四、變數聲明有關
在51系列中data,idata,xdata,pdata的區別 data:固定指前面0x00-0x7f的128個RAM,可以用acc直接讀寫的,速度最快,產生的程式碼也最小。 idata:固定指前面0x00-0xff的256個RAM,其中前128和data的128完全相同,只是因為訪問的方式不同。idata是用類似C中的指標方式訪問的。彙編中的語句為:mox ACC,@Rx.(不重要的補充:c中idata做指標式的訪問效果很好) xdata:外部擴充RAM,一般指外部0x0000-0xffff空間,用DPTR訪問。
pdata:外部擴充RAM的低256個位元組,地址出現在A0-A7的上時讀寫,用movx ACC,@Rx讀寫。這個比較特殊,而且C51好象有對此BUG, 建議少用。但也有他的優點,具體用法屬於中級問題,這裡不提。
startup.a51的作用和彙編一樣,在C中定義的那些變數和數組的初始化就在startup.a51中進行,如果你在定義全域變數時帶有數值,如unsigned char data xxx="100";,那startup.a51中就會有相關的賦值。如果沒有=100,startup.a51就會把他清0。(startup.a51==變數的初始化)。這些初始化完畢後,還會設定SP指標。對非變數地區,如堆棧區,將不會有賦值或清零動作。有人喜歡改startup.a51,為了滿足自己一些想當然的愛好,這是不必要的,有可能錯誤的。比如掉電保護的時候想儲存一些變數,
但改startup.a51來實現是很笨的方法,實際只要利用非變數地區的特性,定義一個指標變數指向堆棧低部:0xff處就可實現。, 為什麼還要去改? 可以這麼說:任何時候都可以不需要改startup.a51,如果你明白它的特性。

五、類型有關
用bit能夠定義一個變數,用sbit卻不行,sbit能夠定義連接埠。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.