Franklin C-51語言程序設(shè)計基礎(chǔ)
1.1Franklin C-51數(shù)據(jù)類型
Franklin C-51編譯器支持下列數(shù)據(jù)類型:
數(shù)據(jù)類型長度值域
bit 1 字節(jié)0 或 1
signed char1 字節(jié)-128~+127
unsigned char1 字節(jié)0~255
signed int2 字節(jié)-32768~+32867
unsigned int2 字節(jié)0~65535
signed long4 字節(jié)-2147483648~+2147483647
unsigned long4 字節(jié)0~4294967295
float 4 字節(jié)±1.176E-38~±3.40E+38
指針 1~3 字節(jié)對象地址
sbit 1 位0 或 1
sfr 1 字節(jié)0~255
sfr16 2 字節(jié)0~65535
編譯的數(shù)據(jù)類型(如結(jié)構(gòu))包含上表所列的數(shù)據(jù)類型。由于8051系列是8位機(jī),因而不存在字節(jié)校準(zhǔn)問題。這意味著數(shù)據(jù)結(jié)構(gòu)成員是順序放
置的。
數(shù)據(jù)類型的轉(zhuǎn)換:當(dāng)計算結(jié)果隱含著另外一種數(shù)據(jù)類型時,數(shù)據(jù)類型可以自動進(jìn)行轉(zhuǎn)換,例如,將一個位變量賦給一個整型變量時,位型
值自動轉(zhuǎn)換為整型值,有符號變量的符號也能自動進(jìn)行處理。這些轉(zhuǎn)換也可以用C語言的標(biāo)準(zhǔn)指令進(jìn)行人工轉(zhuǎn)換。
1.2 數(shù)據(jù)類型的物理結(jié)構(gòu)
1.2.1 bit
“bit”類型只有1位,不允許有位指針和位數(shù)組。位對象始終位于8051 CPU的可尋址RAM空間。如果程序控制流允許,L51將位對象交迭。
1.2.2signed/unsigned char;data/idata/pdata 指針
“char”類型標(biāo)量和基于存貯器的“data/idata/pdata”指針具有1個字節(jié)長度(8 bits)。
1.2.3signed/unsigned int/short;xdata/code 指針
“int”和“short”類型標(biāo)量及指向xdata/code區(qū)域的指針具有2字節(jié)長度(16
bits)。
整型值(或偏移)0x1234以下面方式保存在內(nèi)存中:
地址: +0 +1
內(nèi)容: 0x120x34
1.2.4signed/unsigned long
“l(fā)ong”類型標(biāo)量長為4個字節(jié)(32 bits),值0x12345678以下面方式放置:
地址: +0 +1 +2 +3
內(nèi)容: 0x12 0x34 0x56 0x78
1.2.5“一般”指針
“一般”指針包括3個字節(jié):2字節(jié)偏移和1字節(jié)存貯器類型:
地址:+0 +1 +2
內(nèi)容: 存貯器類型偏移高位 偏移低位
第一個字節(jié)代表了指針的存貯器類型,存貯器類型編碼如下:
存貯器類型 IDATA XDATA PDATADATACODE
值 12 3 4 5
使用其它類型值可能導(dǎo)致不可預(yù)測的程序動作。
XDATA類型的0x1234地址作為指針表示如下:
地址:+0+1 +2
內(nèi)容: 0x02 0x12 0x34
當(dāng)用常數(shù)作指針時,必須注意正確定義存貯器類型和偏移。下例將值0x41寫入絕對地址為0x8000的外部數(shù)據(jù)存貯器:
#defineXBYTE ((char *)0x20000L)
XBYTE[0x8000]=0x41;
上例中用其它常數(shù)索引或索引變量也起作用。這樣,各種存貯器類型的絕對地址可以一種非常有效的方式訪問。但有一個例外,即
SFR。
注意:絕對地址定義為“l(fā)ong”型常量,低16位包含偏移,高8位表明了xdata類型。為了表示這種指針,必須用長整數(shù)來定義存貯器
類型。
C51編譯器不檢查指針常數(shù),用戶必須選擇有實際意義的值。
1.2.6float
“float”類型為4個字節(jié)(32位),使用的格式與IEEE-754標(biāo)準(zhǔn)(32位)具有24位精度,尾數(shù)的高位始終為“1”,因而不保存,位的分布如
下:
l 1位符號
l 8位指數(shù)位
l 23位尾數(shù)
符號位是最高位,尾數(shù)為最低的位,內(nèi)存中按字節(jié)存貯如下:
地址:+0 +1 +2+3
內(nèi)容:MMMM MMMM MMMM MMMME MMM MMMMS EEE EEEE
其中:S:符號位,1=負(fù),0=正
E:指數(shù)(在兩個字節(jié)中),偏移為127
M:23位尾數(shù),最高位“1”
浮點值——12.5的十六進(jìn)制為0xC1480000,它按下面方式存貯:
地址:+0+1+2+3
內(nèi)容: 0x00 0x00 0x48 0xc1
8051不包括捕獲浮點錯誤(例外)的中斷向量。用戶軟件因此必須對錯誤條件作出適當(dāng)反應(yīng)。下面推薦一種方法(也可以用其它可靠
辦法):“union”用來保存浮點值,這個“union”必須包括一個“float”和一個“unsigned long”,以根據(jù)IEEE對錯誤作出響應(yīng)。除了通
常浮點值外,IEEE標(biāo)準(zhǔn)可能出錯的條件以下面二進(jìn)制值表示,為檢查可能出現(xiàn)的計算錯誤,可在計算后進(jìn)行檢查。因為當(dāng)執(zhí)行一個運(yùn)算時考慮
了每個運(yùn)算符的錯誤狀態(tài)并且該狀態(tài)被送到結(jié)果中。
NaN0xFFFFFFF不是一個數(shù)
+INF0x7F80000正無窮(正溢出)
-INF0XFF80000負(fù)無窮(負(fù)溢出)
1.3C-51 的擴(kuò)充定義
1.3.1特殊功能寄存器的聲明
MSC-51 系列包括多種寄存器,其中一些具有特殊功能,如定時器,端口的控制寄存器等,為了能夠直接訪問這些寄存器,C51編譯器提供
了一種定義的自主形式,這是必要的,因為這些定義與標(biāo)準(zhǔn)C語言是不兼容的。
為了支持這些特殊功能寄存器(SFR)的聲明,引入了關(guān)鍵詞“sfr”,語法如下:
sfr-dcl:sfr sfr_name=int_constant
例:
sfr p0=0x80;
sfr p1=0x90;
必須注意的是“sfr”后不是一個地址而是一個名字。因此上例中名字P0和P1(port0和port1)定義為特殊功能寄存器并被賦予相應(yīng)
的絕對地址,名字可按意愿自由選取,源文件中不應(yīng)有先定義的sfr名字。
“=”號后的地址必須是常數(shù),不允許帶有運(yùn)算符的表達(dá)式,這個常數(shù)表達(dá)式必須在特殊功能寄存器的地址范圍內(nèi),位于0X80到0XFF
之間。
8051系列寄存器數(shù)量和類型是極其不同的,因此建議將所有特別的“sfr”聲明放入一個頭文件,頭文件包括8051一些系列成員中的
SFR定義。進(jìn)一步的定義可由用戶用一文件編輯器產(chǎn)生。
1.3.2對SFR的16位數(shù)據(jù)訪問
在新的8051系列產(chǎn)品中,SFR在功能上經(jīng)常組合為16位的,為了有效的訪問這類SFR,使用定義“sfr16”,當(dāng)“SFR”的高端直接位于低端
后時,對SFR16位的訪問是可能的。例如8052的定時器2就是這種情況,16位聲明的語法與“sfr”相同,SFR低地址部分必須作為sfr16的地址
:
例:sfr16 T2=0xCC /*Timer2:T2L=0CCH,T2H=0CDH */
sfr16 RCAP2=0xCA/*RCAP2L=0CAH,PCAP2H=0CBH */
本例中,T2(由T2L和T2H組成)和RCAP2(由RCAP2L和RCAP2H組成)被定義為16位SFR,即使在這種情況下,聲明中的名字后仍不是賦值語句,
而是一個SFR地址,高字節(jié)必須直接位于低字節(jié)之后,這種聲明適用于所有新的SFR,但不能用于Timer0和Timer1。
1.3.3SBIT:特殊功能位聲明
在典型的8051應(yīng)用問題中,經(jīng)常需要單獨(dú)訪問SFR中的位,C51擴(kuò)充功能使之成為可能,特殊位,象SFR一樣,不與標(biāo)準(zhǔn)C語言兼容,使用保留字
“sbit”可訪問位尋址對象。與SFR聲明一樣,用保留字“sbit”聲明某些特殊位接受符號名,“=”后語句將絕對值地址賦給變量名,這種地
址分配有三種方法:
方法1:sfr_name^int_constant
當(dāng)字節(jié)是特殊功能寄存器的地址可用這個方法。sfr_name必須是已定義的SFR的名字,“^”后的語句定義了基地址上的特殊位的位置,該位置
必須是一個0~7的數(shù)。
例: sfr PSW=0xD0;
sfr LE=0xA8;
sbit OV=PSW^2;
sbit CY=PSW^7;
方法2:int_constant^int_constant
這種方法以一整常數(shù)作基地址,該值必須在0x80~0xFF之間,并能被8整除,確定位的位置方法同上。
例: sbit OV=0xD0^2;
sbit CV=0xD0^7;
sbit EA=0xA8^7;
方法3: int_constant
這種方法是將位的絕對地址賦給變量,地址必須位于0x80~0xFF之間。
例: sbit OV=0xD2;
sbit CY=0xD7;
sbit EA=0xAF;
特殊功能位代表了一個獨(dú)立的聲明類,它不能與其它聲明和位域互換。
1.3.4BIT:位標(biāo)量聲明
除了通常的C數(shù)據(jù)類型外,C51編譯器支持“bit”數(shù)據(jù)類型,對此有下列擴(kuò)充與限制:
(1)函數(shù)可包含類型為“bit”的參數(shù),也可將其作為返回值。
bit bfunc(bit b0,bit b1){
/*……*/
return(b1);
}
注:使用禁止中斷(#pragma disable)或包含明確的寄存器組切換(using n)的函數(shù)不能返回位值,在這種情況下,編譯器會識別出來并產(chǎn)
生一個錯誤信息。
(2)位標(biāo)量聲明的語法及C聲明的語義
sta