不 同系列的嵌入式系統(tǒng)的C編譯器,根據(jù)它所對應(yīng)的不同芯片系列有其各自的特點(diǎn),在這里,以KEIL公司的針對51系列的KEILC51編譯器為例,簡要說明 它與ANSI-C的主要區(qū)別,其它的編譯系統(tǒng)與ANSI-C的差別,可具體參照指定編譯系統(tǒng)手冊,找出它們的不同之處。清楚嵌入式系統(tǒng)的C編譯器與標(biāo)準(zhǔn) ANSI-C的區(qū)別是用C編譯器系統(tǒng)進(jìn)行嵌入式系統(tǒng)開發(fā)的前提條件。
不同的嵌入式C編譯系 統(tǒng)之所以與ANSI-C有所不同,主要是由于它們所針對的硬件系統(tǒng)有其各自不同的硬件特點(diǎn),對國內(nèi)開發(fā)人員熟悉的51系列單片機(jī),有著最為豐富的編譯系 統(tǒng),其中最為出色的當(dāng)屬KEIL(也就是大家熟知的FRANKLING,但FRANKLING只相當(dāng)于KEIL的早期產(chǎn)品,它是KEIL公司在美國銷售時(shí) 曾使用的一個(gè)品牌)。
從頭文件來說,51系列有不同的廠家,不同的系列產(chǎn)品,如僅 ATMEL公司就有大家熟悉的89c2051、89c51、89c52以及大家不熟悉的89s8252等系列產(chǎn)品。它們都是基于51系列的芯片,唯一不同 之處在于內(nèi)部資源如定時(shí)器、中斷、I/O等數(shù)量以及功能的不同,為了實(shí)現(xiàn)這些功能,只需將相應(yīng)的功能寄存器的頭文件加載在程序中就可實(shí)現(xiàn)它們所指定的不同 功能。因此,KEILC51系列頭文件集中體現(xiàn)了各系列芯片的不同功能。
從數(shù)據(jù)類型來說,由于8051系列器件包含位操作空間和豐富的位操作指令,直接嵌入式C與ANSI-C相比,比ANSI-C多一種位類型,使得它能如同匯編一樣,靈活的進(jìn)行位指令操作。
從 數(shù)據(jù)存儲類型來說,8051系列有片內(nèi)、片外程序存儲器,片內(nèi)、片外數(shù)據(jù)存儲器,片內(nèi)程序存儲器還分直接尋址區(qū)和間接尋址類型,分別對應(yīng)code、 data、xdata、idata以及根據(jù)51系列特點(diǎn)而設(shè)定的pdata類型,使用不同的存儲器,將使程序執(zhí)行效率不同,在編寫C51程序時(shí),最好指定 變量的存儲類型,這樣將有利于提高程序執(zhí)行效率(此問題將在后面專門講述)。與ANSI-C稍有不同,它只分SAMLL、COMPACT、LARGE模 式,各種不同的模式對應(yīng)不同的實(shí)際硬件系統(tǒng),也將有不同的編譯結(jié)果。
從數(shù)據(jù)運(yùn)算操作和程序 控制語句以及函數(shù)的使用上來講,它們幾乎沒有什么明顯的不同,只是在函數(shù)的使用上,由于嵌入式系統(tǒng)的資源有限,它的編譯系統(tǒng)不允許太多的程序嵌套,C語言 的豐富的庫函數(shù)對程序開發(fā)提供了很大的幫助,但它的庫函數(shù)和ANSI-C也有一些不同之處,從編譯相關(guān)的不同來說,由于51系列是8位機(jī),擴(kuò)展16位字符 不被C51所支持,其次,ANSI-C所具備的遞歸特性不被C51所支持,在C51中,要使用遞歸特性,必須用REENTRANT進(jìn)行申明才能使用。
KEILC51 與標(biāo)準(zhǔn)ANSI-C在庫函數(shù),由于部分庫函數(shù)不適合嵌入式處理系統(tǒng),因此被排除在外,如字符屏幕和圖形函數(shù),也有一些庫函數(shù)繼續(xù)使用,但這些庫函數(shù)是廠家 針對硬件特點(diǎn)相應(yīng)開發(fā)的,它們與ANSI-C的構(gòu)成及用法都有很大不同,如printf和scanf。在ANSI-C中這兩個(gè)函數(shù)通常用于屏幕打和,接收 字符,而在KEILC51中,它們則主要用于串行數(shù)據(jù)的收發(fā)。
ANSI C的標(biāo)準(zhǔn)函數(shù)庫(與之相關(guān)聯(lián)的頭文件):
assert.h
ctype.h
errno.h
float.h
limits.h
locale.h
math.h
setjmp.h
signal.h
stdarg.h
stddef.h
stdio.h
stdlib.h
string.h
time.h
keil c 庫函數(shù)
本征庫函數(shù)(intrinsic routines)和非本征證庫函數(shù) Keil C51庫函數(shù)原型列表
C51強(qiáng)大功能及其高效率的重要體現(xiàn)之一在于其豐富的可直接調(diào)用的庫函數(shù),多使用庫函數(shù)使程序代碼簡單,結(jié)構(gòu)清晰,易于調(diào)試和維護(hù),下面介紹C51的庫函數(shù)系統(tǒng)。
C51提供的本征函數(shù)是指編譯時(shí)直接將固定的代碼插入當(dāng)前行,而不是用ACALL和LCALL語句來實(shí)現(xiàn),這樣就大大提供了函數(shù)訪問的效率,而非本征函數(shù)則必須由ACALL及LCALL調(diào)用。
C51的本征庫函數(shù)只有9個(gè),數(shù)目雖少,但都非常有用,列如下:
_crol_,_cror_:將char型變量循環(huán)向左(右)移動指定位數(shù)后返回
_iror_,_irol_:將int型變量循環(huán)向左(右)移動指定位數(shù)后返回
_lrol_,_lror_:將long型變量循環(huán)向左(右)移動指定位數(shù)后返回
_nop_: 相當(dāng)于插入NOP
_testbit_: 相當(dāng)于JBC bitvar測試該位變量并跳轉(zhuǎn)同時(shí)清除。
_chkfloat_: 測試并返回源點(diǎn)數(shù)狀態(tài)。
使用時(shí),必須包含#inclucle <intrins.h>一行。
如不說明,下面談到的庫函數(shù)均指非本征庫函數(shù)。
第二節(jié) 幾類重要庫函數(shù)
1. 專用寄存器include文件
例如8031、8051均為REG51.h其中包括了所有8051的SFR及其位定義,一般系統(tǒng)都必須包括本文件。
2. 絕對地址include文件absacc.h
該文件中實(shí)際只定義了幾個(gè)宏,以確定各存儲空間的絕對地址。
3. 動態(tài)內(nèi)存分配函數(shù),位于stdlib.h中
4. 緩沖區(qū)處理函數(shù)位于“string.h”中
其中包括拷貝比較移動等函數(shù)如:
memccpy memchr memcmp memcpy memmove memset
這樣很方便地對緩沖區(qū)進(jìn)行處理。
5. 輸入輸出流函數(shù),位于“stdio.h”中
流函數(shù)通8051的串口或用戶定義的I/O口讀寫數(shù)據(jù),缺省為8051串口,如要修改,比如改為LCD顯示,可修改lib目錄中的getkey.c及putchar.c源文件,然后在庫中替換它們即可。