先來簡單說說C語言的標識符和關(guan) 鍵字。標識符是用來標識源程序中某個(ge) 對象的名字的,這些對象可以是語句、數據類型、函數、變量、數組等等。C語言是大小字敏感的一種高級語言,如果我們(men) 要定義(yi) 一個(ge) 定時器1,可以寫(xie) 做"Timer1",如果程序中有"TIMER1",那麽(me) 這兩(liang) 個(ge) 是完全不同定義(yi) 的標識符。標識符由字符串,數字和下劃線等組成,注意的是第一個(ge) 字符必須是字母或下劃線,如"1Timer"是錯誤的,編譯時便會(hui) 有錯誤提示。有些編譯係統專(zhuan) 用的標識符是以下劃線開頭,所以一般不要以下劃線開頭命名標識符。標識符在命名時應當簡單,含義(yi) 清晰,這樣有助於(yu) 閱讀理解程序。在C51編譯器中,隻支持標識符的前32位為(wei) 有效標識,一般情況下也足夠用了,除非你要寫(xie) 天書(shu) :P。
關(guan) 鍵字則是編程語言保留的特殊標識符,它們(men) 具有固定名稱和含義(yi) ,在程序編寫(xie) 中不允許標識符與(yu) 關(guan) 鍵資亦同。在KEIL uVision2中的關(guan) 鍵字除了有ANSI C標準的32個(ge) 關(guan) 鍵字外還根據51單片機的特點擴展了相關(guan) 的關(guan) 鍵字。其實在KEIL uVision2的文本編輯器中編寫(xie) C程序,係統可以把保留字以不同顏色顯示,缺省顏色為(wei) 天藍色。()
先看表4-1,表中列出了KEIL uVision2 C51編譯器所支持的數據類型。在標準C語言中基本的數據類型為(wei) char,int,short,long,float和double,而在C51編譯器中int和short相同,float和double相同,這裏就不列出說明了。下麵來看看它們(men) 的具體(ti) 定義(yi) :
數據類型 |
長 度 |
值 域 |
unsigned char |
單字節 |
0~255 |
signed char |
單字節 |
-128~+127 |
unsigned int |
雙字節 |
0~65535 |
signed int |
雙字節 |
-32768~+32767 |
unsigned long |
四字節 |
0~4294967295 |
signed long |
四字節 |
-2147483648~+2147483647 |
float |
四字節 |
±1.175494E-38~±3.402823E+38 |
* |
1~3字節 |
對象的地址 |
bit |
位 |
0或1 |
sfr |
單字節 |
0~255 |
sfr16 |
雙字節 |
0~65535 |
sbit |
位 |
0或1 |
表4-1 KEIL uVision2 C51編譯器所支持的數據類型
1. char字符類型
char類型的長度是一個(ge) 字節,通常用於(yu) 定義(yi) 處理字符數據的變量或常量。分無符號字符類型unsigned char和有符號字符類型signed char,默認值為(wei) signed char類型。unsigned char類型用字節中所有的位來表示數值,所可以表達的數值範圍是0~255。signed char類型用字節中最高位字節表示數據的符號,"0"表示正數,"1"表示負數,負數用補碼表示。所能表示的數值範圍是-128~+127。unsigned char常用於(yu) 處理ASCII字符或用於(yu) 處理小於(yu) 或等於(yu) 255的整型數。
*正數的補碼與(yu) 原碼相同,負二進製數的補碼等於(yu) 它的絕對值按位取反後加1。
2. int整型
int整型長度為(wei) 兩(liang) 個(ge) 字節,用於(yu) 存放一個(ge) 雙字節數據。分有符號int整型數signed int和無符號整型數unsigned int,默認值為(wei) signed int類型。signed int表示的數值範圍是-32768~+32767,字節中最高位表示數據的符號,"0"表示正數,"1"表示負數。unsigned int表示的數值範圍是0~65535。
好了,先停一下吧,我們(men) 來寫(xie) 個(ge) 小程序看看unsigned char和unsigned int用於(yu) 延時的不同效果,說明它們(men) 的長度是不同的,嗬,盡管它並沒有實際的應用意義(yi) ,這裏我們(men) 學習(xi) 它們(men) 的用法就行。依舊用我們(men) 上一課的最小化係統做實驗,不過要加多一個(ge) 電阻和LED,如圖4-1。實驗中用D1的點亮表明正在用unsigned int數值延時,用D2點亮表明正在用unsigned char數值延時。

圖4-1 第4課實驗用電路
我們(men) 把這個(ge) 項目稱為(wei) TwoLED,實驗程序如下:
#include <AT89X51.h> //預處理命令
void main(void) //主函數名
{
unsigned int a; //定義(yi) 變量a為(wei) unsigned int類型
unsigned char b; //定義(yi) 變量b為(wei) unsigned char類型
do
{//do while組成循環
for (a=0; a<65535; a++)
P1_0 =0; //65535次設P1.0口為(wei) 低電平,點亮LED
P1_0 =1; //設P1.0口為(wei) 高電平,熄滅LED
for (a=0; a<30000; a++); //空循環
for (b=0; b<255; b++)
P1_1 =0; //255次設P1.1口為(wei) 低電平,點亮LED
P1_1 =1; //設P1.1口為(wei) 高電平,熄滅LED
for (a=0; a<30000; a++); //空循環
}
while(1);
}
同樣編譯燒寫(xie) ,上電運行您就可以看到結果了。很明顯D1點亮的時間長於(yu) D2點亮的時間。程序中的循環延時時間並不是很好確定,並不太適合要求精確延時的場合,關(guan) 於(yu) 這方麵我們(men) 以後也會(hui) 做討論。這裏必須要講的是,當定義(yi) 一個(ge) 變量為(wei) 特定的數據類型時,在程序使用該變量不應使它的值超過數據類型的值域。如本例中的變量b不能賦超出0~255的值,如for (b=0; b<255; b++)改為(wei) for (b=0; b<256; b++),編譯是可以通過的,但運行時就會(hui) 有問題出現,就是說b的值永遠都是小於(yu) 256的,所以無法跳出循環執行下一句P1_1 = 1,從(cong) 而造成死循環。同理a的值不應超出0~65535。大家可以燒片看看實驗的運行結果,同樣軟件仿真也是可以看到結果的。
3. long長整型
long長整型長度為(wei) 四個(ge) 字節,用於(yu) 存放一個(ge) 四字節數據。分有符號long長整型signed long和無符號長整型unsigned long,默認值為(wei) signed long類型。signed int表示的數值範圍是-2147483648~+2147483647,字節中最高位表示數據的符號,"0"表示正數,"1"表示負數。unsigned long表示的數值範圍是0~4294967295。
4. float浮點型
float浮點型在十進製中具有7位有效數字,是符合IEEE-754標準的單精度浮點型數據,占用四個(ge) 字節。因浮點數的結構較複雜在以後的章節中再做詳細的討論。 5.* 指針型
指針型本身就是一個(ge) 變量,在這個(ge) 變量中存放的指向另一個(ge) 數據的地址。這個(ge) 指針變量要占據一定的內(nei) 存單元,對不同的處理器長度也不盡相同,在C51中它的長度一般為(wei) 1~3個(ge) 字節。指針變量也具有類型,在以後的課程中有專(zhuan) 門一課做探討,這裏就不多說了。
6. bit位標量
bit位標量是C51編譯器的一種擴充數據類型,利用它可定義(yi) 一個(ge) 位標量,但不能定義(yi) 位指針,也不能定義(yi) 位數組。它的值是一個(ge) 二進製位,不是0就是1,類似一些高級語言中的Boolean類型中的True和False。
7. sfr特殊功能寄存器
sfr也是一種擴充數據類型,點用一個(ge) 內(nei) 存單元,值域為(wei) 0~255。利用它可以訪問51單片機內(nei) 部的所有特殊功能寄存器。如用sfr P1 =0x90這一句定P1為(wei) P1端口在片內(nei) 的寄存器,在後麵的語句中我們(men) 用以用P1 = 255(對P1端口的所有引腳置高電平)之類的語句來操作特殊功能寄存器。
8.sfr16 16位特殊功能寄存器
sfr16占用兩(liang) 個(ge) 內(nei) 存單元,值域為(wei) 0~65535。sfr16和sfr一樣用於(yu) 操作特殊功能寄存器,所不同的是它用於(yu) 操作占兩(liang) 個(ge) 字節的寄存器,好定時器T0和T1。
9. sbit可錄址位
sbit同位是C51中的一種擴充數據類型,利用它可以訪問芯片內(nei) 部的RAM中的可尋址位或特殊功能寄存器中的可尋址位。如先前我們(men) 定義(yi) 了
sfr P1 =0x90; //因P1端口的寄存器是可位尋址的,所以我們(men) 可以定義(yi)
sbit P1_1 = P1^1; //P1_1為(wei) P1中的P1.1引腳
//同樣我們(men) 可以用P1.1的地址去寫(xie) ,如sbit P1_1 = 0x91;
這樣我們(men) 在以後的程序語句中就可以用P1_1來對P1.1引腳進行讀寫(xie) 操作了。通常這些可以直接使用係統提供的預處理文件,裏麵已定義(yi) 好各特殊功能寄存器的簡單名字,直接引用可以省去一點時間,我自己是一直用的。當然您也可以自己寫(xie) 自己的定義(yi) 文件,用您認為(wei) 好記的名字。
關(guan) 於(yu) 數據類型轉換等相關(guan) 操作在後麵的課程或程序實例中將有所提及。大家可以用所講到的數據類型改寫(xie) 一下這課的實例程序,加深對各類型的認識。