新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ASM5無參數(shù)化調用C51函數(shù)的實現(xiàn)

ASM5無參數(shù)化調用C51函數(shù)的實現(xiàn)

作者: 時間:2012-03-08 來源:網(wǎng)絡 收藏

MCS -51系列單片機在目前和今后的相當一段時間內都將是我國的單片機主流機種。但在早期的開發(fā)過程中,程序員不得不從深奧的開始摸索,同時要求開發(fā)人員對硬件亦有相當?shù)淖咏?。相比而言,專?051系列單片機設計的Franklin 是一種通用的高級結構化的程序設計語言。入門容易,程序可讀性強,調試、移植都很方便,故開發(fā)效率高,尤其在數(shù)值運算處理方便具有很大的優(yōu)勢(這正是ASM51的薄弱環(huán)節(jié))。不過,C語言雖然也可對計算機的硬件系統(tǒng)進行操作,但在處理特殊I/O口和中斷向量方面,不如匯編那樣直接、有效。因而,在效率為重的今天,將ASM51匯編與結合起來,充分發(fā)揮各自的優(yōu)勢,無疑是單片機開發(fā)人員的最佳選擇。

1 匯編與C51的混合編程

一般的做法都是利用C51上手容易、便于理解的優(yōu)勢來編寫主程序,在不便處理或者效率比較低時調用匯編函數(shù)??紤]到MCS-51(尤其是8031 內部的資源配置情況:可用的RAM不到256字節(jié),5個固定地址的有限中斷源,4個8位并口中實際可作I/O口的只有P1口。因而要求開發(fā)都對單片機的內部結構有清楚的了解,并盡可能地統(tǒng)籌安排這些資源。事實也證明,不理解是很難寫出高效程序的。故筆者的觀點是利用匯編語言對I/O接口、中斷向量及程序空間分配的茂大優(yōu)勢,讓程序員對MCS-51內的第一個字節(jié)甚至是每一比特(可位尋址的空間)全部進行統(tǒng)籌安排,設計好各個程序模塊,包括I/O口地址和中斷向量地址的處理;同時在具體的數(shù)據(jù)處理、通信等不需要過多與硬件直接打交道的程序模塊中,充分利用C51語言強大高效的編程能力。

最后的關鍵是如何讓匯編模塊能正確識別C51函數(shù)并調用它來完成相應的功能。ASM51匯編與C51 語言之間的調用約定并不簡單,而且各種編譯器使用的約定不盡相同,甚至還依賴于程序所選擇的大、中、小存儲模式。通常每個需傳遞的參數(shù)按調用順序和類型分別由約定的寄存器來傳遞。如果參數(shù)過多或者無足夠寄存器可用時,參數(shù)的傳遞將在固定持存儲器區(qū)域內進行,相同類型的參數(shù)共享一個參數(shù)傳遞段,按參數(shù)調用順序遞增其存放地址,返回值也由約定的寄存器或地址段返回。由此可見程序調用的效率必將受到接口復雜度的影響。盡管目前的單片機仿真器已經(jīng)提供了標準接口的全自動轉換功能,減少了接口工作量,但在程序的調試及移植中,如果程序員不了解這些接口的各種約定,將對出現(xiàn)的錯誤不知所措。比如返回值不止一個時,編譯器自己就無法正確完成接口配置。這里力薦一種簡潔有效的調用方法——。

2 ASM51C51函數(shù)的實現(xiàn)原理

所謂的是指讓C51子函數(shù)不帶任何參數(shù),這樣就可以從根本上避開調用參數(shù)的傳遞和返回值的安排等繁瑣易出錯的問題,只需要簡單地在匯編語言開頭說明一下外部C51子函數(shù)(“EXTRN code(C51模塊名稱>)”)。至于C51函數(shù)中需要使用的外部參數(shù)值及其返回值,完全可以通過加入C51 的absacc.h>頭文件來解決。

absacc.h>頭文件中的函數(shù)原型為:

# define CBYTE((unsigned char *)0x50000L)

# define DBYTE ((unsigned char *)0x50000L)

# define PBYTE ((unsigned char *)0x50000L)

# define XBYTE((unsigned char *)0x50000L)

其中CBYTE定義為尋址CODE程序區(qū);DBYTE定義為尋址DATA數(shù)據(jù)區(qū);PBYTE定義為尋址相對于MOVX @R0"指令的分頁數(shù)據(jù)XDATA區(qū);XBYTE定義為尋址相對于MOVX @DPTR"指令的分布數(shù)據(jù)XDATA區(qū)。它們的類型決定了絕對地址空間的位置。

引進該頭文件后,程序員就可以對8051系列單片機的存儲器進行絕對地址的訪問,把對參數(shù)值和返回值的操作轉化為對存儲器絕對地址的操作,像純匯編操作一樣,根本不用定義C51函數(shù)與匯編接口的參數(shù)和返回值的配置,從而提高了調用效率。具體做法是:先在 C51函數(shù)中定義好傳遞參數(shù)和返回值所需要的各個絕對地址(視程序員自己的空間配置而定),在其它匯編模塊中將C51函數(shù)中將要使用的參數(shù)值放入這些絕對地址中,把被調用C51模塊將輸出的計算值(可以不止一個)也放入類似的絕對地址中。于是,當C51函數(shù)中需要使用某個參數(shù)值時,就直接從相應的絕對地址中讀取該值;當別的匯編模塊中需要使用C51函數(shù)返回值時,也直接對存放返回值的絕對地址進行讀操作即可。下面以一個調試通過的匯編調用C51函數(shù)的簡單程序為例進行具體說明。

3 ASM51無參數(shù)化調用C51函數(shù)的實現(xiàn)示例

該系統(tǒng)要示然而單片機根據(jù)實時采樣輸入的轉速實現(xiàn)機車速度的測量,并可隨鍵盤輸入的車輪直徑變化實時調整車速,最后將車速和輪徑值都顯示出來。設計任務很簡單,編程中的最大難度就在于車速的計算程序。由于輪徑值要求精確到mm(最大值超過了1000),車速的計算結果要保留到小數(shù)點后一位,因此需要進行浮點數(shù)運算,期間還要完成數(shù)的各種進制間的換算。雖然算法簡單,但實際用匯編語言實現(xiàn)起來經(jīng)??紤]不周,調試起來費時費力(筆者調試通過的這段匯編代碼長達近 400行)。這樣,自然就想到調用C51函數(shù)了,充發(fā)發(fā)揮兩種語言的優(yōu)勢。先用匯編語言設計好各個模塊,包括循環(huán)顯示車速和輪徑值的主程序模塊,響應采樣轉速值和鍵盤輸入兩個中斷模塊,代碼如下所示。

EXTRN CODE(CALL1) ;聲明外部C51函數(shù)

ORG 0000H

LJMP MAIN

ORG 0003H

AJMP KEYINPUT ;鍵盤輸入中斷

ORG 000BH

AJMP SETTIME ;采樣時間到,采樣轉速值中斷

ORG 0100H

KEYINPUT:…… ;鍵盤輸入中斷

…… ;將鍵盤輸入信號保存在

;70h~73h的地址空間中

RETI

ORG 0600H

SETTIME:…… ;采樣時間到,采樣轉速值中斷

…… ;將轉速值放置在地址為3Ah的空間中

;緊接著調用外部C51函數(shù)CALL1()進

;行車速的計算

LCALL CALL1

RETI

ORG 2000H ;主程序模塊

MAIN:…… ;首先進行初始化操作

……

;直接從地址空間70h~77h中讀取顯示數(shù)據(jù),循環(huán)顯示車速和輪徑值

END


上一頁 1 2 下一頁

評論


相關推薦

技術專區(qū)

關閉