C51語言
本文主要涉及C51語言的一些基本知識,比如C51語言的數據類型以及存儲類型以及一些基本運算。
文章目錄
- C51語言
- 一、 C51與標準C的比較
- 二、 C51語言中的數據類型與存儲類型
- 2.1、C51的擴展數據類型
- 2.2、數據存儲類型
- 三、 C51的基本運算
- 3.1 算術運算符
- 3.2 邏輯運算符
- 3.3 關系運算符
- 3.4 位運算
- 3.5 指針和取地址運算符
一、 C51與標準C的比較
C51的基本語法與標準C相同,C51在標準C的基礎上進行了適合于51系列單片機硬件的擴展。
深入理解Keil C51對標準C的擴展部分以及不同之處,是掌握C51語言的關鍵之一。
C51與標準C的主要區別
如下:
(1)庫函數的不同。
(2)數據類型有一定的區別。
(3)C51的變量存儲模式與標準C中的變量存儲模式數據不一樣。
(4)數據存儲類型的不同。
(5)標準C語言沒有處理單片機中斷的定義。
(6)C51語言與標準C語言的輸入/輸出處理不一樣。
(7)頭文件的不同。
(8)程序結構的差異。
但是從數據運算操作、程序控制語句以及函數的使用上來說,Keil C51與標準C幾乎沒有什么明顯的差別。
二、 C51語言中的數據類型與存儲類型
Keil C51支持的基本數據類型如表3-1所示。針對AT89S51單片機的硬件特點,C51在標準C的基礎上,擴展了4種數據類型(表3-1中最后4行)。
注意:擴展的4種數據類型,不能使用指針對它們存取。
2.1、C51的擴展數據類型
對擴展的4種數據類型說明:
(1)位變量bit
bit的值可以是1(true)
, 也可以是0(false)
(2)特殊功能寄存器sfr
特殊功能寄存器分布在片內數據存儲區
的地址單元80H~FFH
之間,“sfr” 數據類型占用一個
內存單元。利用它可以訪問單片機內部的所有特殊功能寄存器
。
例如:sfr P1=0x90
3)特殊功能寄存器sfr16
“sfr16”數據類型占兩個內存單元
。它用于操作占兩個字節的特殊功能寄存器。
例如: “sfr16 DPTR=0x82”語句定義了片內16位數據指針寄存器DPTR,其低8位字節地址為82H,高8位字節地址為83H。
(4)特殊功能位 sbit
sbit—片內特殊功能寄存器的可尋址位
。
例如:
sfr PSW=0xd0; /定義PSW寄存器地址為0xd0/
sbit PSW^2 = 0xd2; /定義OV位為PSW.2/
符號“”`前`是特殊功能寄存器的`名字`,“”的后
面數字是特殊功能寄存器可尋址位在寄存器中的位置
,取值必須是0~7
。
注意,不要把bit與sbit混淆。
bit
是定義普通的位變量
,值只能是二進制的0或1
。而sbit
定義的是特殊功能寄存器的可尋址位
,它的值是可進行位尋址的特殊功能寄存器的某位的絕對地址
。
2.2、數據存儲類型
51單片機有片內、外數據存儲區
,還有程序存儲區
。51單片機片內的數據存儲區是可讀寫的,51單片機的衍生系列最多可有256個字節的內部數據存儲區,其中低128字節可直接尋址
,高128字節(80H~FFH)只能間接尋址
,從20H開始的16字節可位尋址。
程序存儲區只能讀不能寫,可能在51單片機內部或者外部,或者外部和內部都有,由51單片機的硬件決定。
內部數據存儲區可分為3個不同的數據存儲類型:data、idata和bdata。
訪問片外數據存儲區比訪問片內數據存儲區慢
,C51提供兩種
不同數據存儲類型xdata
和pdata
來訪問片外數據存儲區
。
下面對表3-2中的各種存儲區作以說明。
(1)DATA區。
尋址是最快的,應該把經常使用的變量
放在DATA區,但是DATA區的存儲空間是有限的,DATA區除了包含程序變量
外,還包含了堆棧
和寄存器組
。可直接尋址
。
聲明舉例如下:
- unsigned char data system_status=0;
- unsigned int data unit_id[8];
- char data inp_string[20];
另外,當內部堆棧溢出
的時候,程序會莫名其妙地復位
。這是因為51單片機沒有報錯的機制,堆棧的溢出只能以這種方式表示,因此要留有較大的堆棧空間來防止堆棧溢出。
(2)BDATA區。
是DATA中的位尋址區,在這個區中聲明變量就可進行位尋址
。BDATA區聲明中的存儲類型標識符為bdata
,指的是內部RAM
可位尋址的16字節存儲區(字節地址為20H~2FH)中的128個位
。
下面是在BDATA區中聲明的位變量和使用位變量的例子:
- unsigned char
bdata
status_byte; - unsigned int bdata status_word;
- sbit stat_flag=
status_byte^4
; - if(status_word^15)
{ …… }
stat_flag=1;
C51編譯器不允許在BDATA區中聲明float和double型變量。
(3)IDATA區。
IDATA區使用寄存器作為指針
來進行間接尋址,常用來存放使用比較頻繁的變量
。與外部存儲器尋址相比,它的指令執行周期和代碼長度相對較短
。指的是片內RAM的256字節的存儲區
,只能間接尋址
,速度比直接尋址慢。
聲明舉例如下:
- unsigned char
idata
system_status=0; - unsigned int idata unit_id[8];
- char idata inp_string[16];
- float idata out_value;
(4)PDATA區和XDATA區。
PDATA區和XDATA區位于片外存儲區
,PDATA區和XDATA區聲明中的存儲類型標識符分別為pdata和xdata。
PDATA區只有256
字節,僅指定256字節的外部數據存儲區。但XDATA區最多可達64KB,對應的xdata存儲類型標識符可以指定外部數據區64KB內的任何地址。
對PDATA區的尋址要比對XDATA區尋址快,因為對PDATA區尋址,只需要裝入8位地址,而對XDATA區尋址要裝入16位地址,所以要盡量把外部數據存儲在PDATA區中。
對PDATA區和XDATA區的聲明舉例如下:
- unsigned char
xdata
system_status=0; - unsigned int pdata unit_id[8];
- char xdata inp_string[16];
- float pdata out_value;
(5)程序存儲區CODE。
程序存儲區CODE聲明的標識符為code,儲存的數據是不可改變的。在C51編譯器中可以用存儲區類型標識符code來訪問程序存儲區。
聲明舉例如下:
unsigned char code
a[ ] ={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
三、 C51的基本運算
C51語言的基本運算與標準C類似,主要包括算術運算、關系運算、邏輯運算、位運算和賦值運算及其表達式等。
3.1 算術運算符
算術運算的算術運算符及其說明如表3-4所示。
表3-4中的自增和自減運算符
是使變量自動加1或減1,自增和自減運算符放在變量前和變量之后是不同的
。
例如:
++i,–i:在使用i之前
,先使i值加
(減)1。
i++,i–:在使用i之后
,再
使i值加(減)1。
例如:若i=4,則執行x=++i時,先使i加1,再引用結果,即x=5,運算結果為i=5,x=5。
再如:若i=4,則執行x=i++時,先引用i值,即x=4,再使i加1,運算結果為i=5,x=4。
3.2 邏輯運算符
邏輯運算符及其說明如表3-5所示。
3.3 關系運算符
關系運算符就是判斷兩個數之間的關系。關系運算符及其說明如表3-6所示。
3.4 位運算
位運算符及其說明如表3-7所示
3.5 指針和取地址運算符
取內容和取地址的一般形式分別為:
變量=*指針變量
指針變量=&目標變量
取內容運算是將指針變量所指向的目標變量的值
賦給左邊的變量;取地址運算是將目標變量的地址
賦給左邊的變量。
注意,指針變量
中只能存放地址
(也就是指針型數據),一般情況下不要將非指針類型的數據賦值給一個指針變量。