C51程序設(shè)計(jì)語(yǔ)言課件_第1頁(yè)
C51程序設(shè)計(jì)語(yǔ)言課件_第2頁(yè)
C51程序設(shè)計(jì)語(yǔ)言課件_第3頁(yè)
C51程序設(shè)計(jì)語(yǔ)言課件_第4頁(yè)
C51程序設(shè)計(jì)語(yǔ)言課件_第5頁(yè)
已閱讀5頁(yè),還剩60頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

C51程序設(shè)計(jì)語(yǔ)言基礎(chǔ)

C51程序設(shè)計(jì)語(yǔ)言C51的運(yùn)算符和表達(dá)式

C51的頭文件與庫(kù)函數(shù)

C51程序設(shè)計(jì)及應(yīng)用

C51的應(yīng)用技巧隨著80C51單片機(jī)硬件性能的提升,尤其是片內(nèi)程序存儲(chǔ)器容量的增大和時(shí)鐘工作頻率的提高,已基本克服了高級(jí)語(yǔ)言產(chǎn)生代碼長(zhǎng)、運(yùn)行速度慢、不適合單片機(jī)使用的致命缺點(diǎn)。由此C51已經(jīng)得到廣泛的推廣和應(yīng)用。采用C51程序設(shè)計(jì)語(yǔ)言,編程者只需了解變量和常量的存儲(chǔ)類型與80C51單片機(jī)存儲(chǔ)空間的對(duì)應(yīng)關(guān)系,而不必深入了解單片機(jī)的硬件和接口。C51編譯器會(huì)自動(dòng)完成變量的存儲(chǔ)單元的分配。

C51程序設(shè)計(jì)語(yǔ)言C51語(yǔ)言概述成于大氣信達(dá)天下C51語(yǔ)言的特點(diǎn)C提供了很多數(shù)學(xué)函數(shù)并支持浮點(diǎn)運(yùn)算,開(kāi)發(fā)效率高,故可縮短開(kāi)發(fā)時(shí)間,增加程序可讀性和可維護(hù)性C語(yǔ)言程序本身不依賴于機(jī)器硬件系統(tǒng),基本上不作修改就可將程序從不同的單片機(jī)中移植過(guò)來(lái)C語(yǔ)言作為一種非常方便的語(yǔ)言而得到廣泛的支持,國(guó)內(nèi)最通用的是KeilC51#include<reg51.h> /*文件包含,51寄存器說(shuō)明*/main() /*主函數(shù)*/{intx,y,z; /*變量定義(變量類型)*/if(x>y)z=x; /*運(yùn)算符,基本語(yǔ)句*/elsez=y; }★C51程序示例:C51的程序結(jié)構(gòu)與一般C語(yǔ)言的結(jié)構(gòu)相同,以main()函數(shù)為程序入口,程序體中包含若干語(yǔ)句還可以包含若干函數(shù)。C-51函數(shù)的一般格式

類型函數(shù)名(參數(shù)表)

{

數(shù)據(jù)說(shuō)明部分語(yǔ)句執(zhí)行部分

}①程序由函數(shù)組成(一個(gè)主函數(shù),或一個(gè)主函數(shù)和若干自定義函數(shù));②利用預(yù)處理命令對(duì)變量或函數(shù)進(jìn)行集中定義或說(shuō)明;③函數(shù)和變量都需遵循先定義后使用的基本原則;④主函數(shù)中的所有語(yǔ)句執(zhí)行完畢,則程序結(jié)束。C51與標(biāo)準(zhǔn)C程序結(jié)構(gòu)完全相同舉例:LED閃爍控制功能預(yù)處理命令---------函數(shù)說(shuō)明------------全局變量定義------

主函數(shù)------------調(diào)用函數(shù)------------局部變量定義---------

程序體

程序體------C51簡(jiǎn)單例題#include"AT89X51.H"http://包含頭文件voidmain(void)//主程序{while(1)//無(wú)限循環(huán){P2_0=0;//亮燈P2_0=1;//滅燈}}成于大氣信達(dá)天下一、C51中常用的頭文件Reg52.h

(定義單片機(jī)的特殊功能寄 存器和端口)Stdio.h

(標(biāo)準(zhǔn)輸入輸出函數(shù)庫(kù))Math.h

(標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)庫(kù))Absacc.h

(外部絕對(duì)地址訪問(wèn)函數(shù)庫(kù))Ctype.h

(字符函數(shù)庫(kù))Stdlib.h

(數(shù)學(xué)函數(shù)庫(kù))其它部分頭文件:(1)頭文件ctype.h字符處理函數(shù)本類別函數(shù)用于對(duì)單個(gè)字符進(jìn)行處理,包括字符的類別測(cè)試和字符的大小寫轉(zhuǎn)換(2)頭文件local.h

地區(qū)化本類別的函數(shù)用于處理不同國(guó)家的語(yǔ)言差異。(3)頭文件math.h函數(shù)列表函數(shù)類別函數(shù)用途詳細(xì)說(shuō)明,如三角函數(shù)反余弦acos

反正弦asinC51常用頭文件:(4)頭文件signal.h信號(hào)處理該分類函數(shù)用于處理那些在程序執(zhí)行過(guò)程中發(fā)生例外的情況(5)頭文件stdio.h輸入輸出函數(shù)該分類用于處理包括文件、控制臺(tái)等各種輸入輸出設(shè)備,各種函數(shù)以“流”的方式實(shí)現(xiàn)如:打開(kāi)文件fopen格式化輸入與輸出函數(shù)格式輸出fprintf格式輸入fscanf格式輸出(控制臺(tái))printf

格式輸入(控制臺(tái))scanf宏定義

在C語(yǔ)言源程序中允許用一個(gè)標(biāo)識(shí)符來(lái)表示一個(gè)字符串,稱為“宏”。被定義為“宏”的標(biāo)識(shí)符稱為“宏名”。在編譯預(yù)處理時(shí),對(duì)程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開(kāi)”。宏定義是由源程序中的宏定義命令完成的。宏代換是由預(yù)處理程序自動(dòng)完成的。宏定義的一般形式為:

#define標(biāo)識(shí)符字符串“define”為宏定義命令?!皹?biāo)識(shí)符”為所定義的宏名?!白址笨梢允浅?shù)、表達(dá)式、或含有參數(shù)的表達(dá)式、格式串等。在程序中多次使用宏,可以簡(jiǎn)化源程序的輸入。與使用函數(shù)相比,會(huì)占用較多內(nèi)存,但執(zhí)行速度快。例如:

#defineM(y*y+3*y)文件包含命令

文件包含是C預(yù)處理程序的另一個(gè)重要功能。文件包含是用指定文件的全部?jī)?nèi)容替換該預(yù)處理命令行。即一個(gè)程序文件將另一個(gè)指定文件的內(nèi)容完全包含進(jìn)來(lái)。在程序設(shè)計(jì)中,文件包含是很有用的。一個(gè)大的程序可以分為多個(gè)模塊,由多個(gè)程序員分別編程。有些公用的符號(hào)常量或宏定義等可單獨(dú)組成一個(gè)文件,在其它文件的開(kāi)頭用包含命令包含該文件即可使用。這樣,可避免在每個(gè)文件開(kāi)頭都去書寫那些公用量,從而節(jié)省時(shí)間,并減少出錯(cuò)。

#include"文件名"

或: #include<文件名>

。文件包含的對(duì)象最為常見(jiàn)的是頭文件(擴(kuò)展名.h)。在前面我們已多次用此命令包含過(guò)庫(kù)函數(shù)的頭文件。文件包含命令行的一般形式為:二、C51的標(biāo)識(shí)符、常量和關(guān)鍵字標(biāo)識(shí)符用來(lái)標(biāo)識(shí)源程序中某個(gè)對(duì)象的名字,這些對(duì)象可以是語(yǔ)句、數(shù)據(jù)類型、函數(shù)、變量、數(shù)組等。標(biāo)識(shí)符區(qū)分大小寫,第一個(gè)字符必須是字母或下劃線。C51中有些庫(kù)函數(shù)的標(biāo)識(shí)符是以下劃線開(kāi)頭的,所以一般不要以下劃線開(kāi)頭命名標(biāo)識(shí)符。常量:凡以數(shù)字0開(kāi)頭的數(shù)字序列,一律作為八進(jìn)制數(shù)處理;凡以0x開(kāi)頭,后面跟若干數(shù)字的,一律作為十六進(jìn)制數(shù)處理;其它作為十進(jìn)制數(shù)處理。關(guān)鍵字:ANSIC標(biāo)準(zhǔn)關(guān)鍵字和C51編譯器的擴(kuò)展關(guān)鍵字C51擴(kuò)展的若干關(guān)鍵字一覽表

變量名不得使用標(biāo)準(zhǔn)C語(yǔ)言和C51語(yǔ)言的關(guān)鍵字。C51的變量

在程序執(zhí)行過(guò)程中,數(shù)值可以發(fā)生改變的量稱為變量。變量名與存儲(chǔ)單元地址相對(duì)應(yīng),變量值與存儲(chǔ)單元的內(nèi)容相對(duì)應(yīng)。例如在哈佛結(jié)構(gòu)的存儲(chǔ)空間中如何建立變量概念?【存儲(chǔ)種類】數(shù)據(jù)類型【存儲(chǔ)類型】

變量名(標(biāo)準(zhǔn)C)(標(biāo)準(zhǔn)C)*括號(hào)項(xiàng)——可以缺省(但需有缺省值)C51變量定義的四要素:(C51特有)(標(biāo)準(zhǔn)C+C51)【存儲(chǔ)種類】

數(shù)據(jù)類型【存儲(chǔ)類型】變量名共有四個(gè)說(shuō)明符:1、auto(自動(dòng)型)——變量的作用范圍在定義它的函數(shù)體或語(yǔ)句塊內(nèi)。執(zhí)行結(jié)束后,變量所占內(nèi)存即被釋放。2、extern(外部型)——在一個(gè)源文件中被定義為外部型的變量,在其它源文件中需要通過(guò)extern說(shuō)明方可使用。3、static(靜態(tài)型)——利用static可使變量定義所在的函數(shù)或語(yǔ)句塊執(zhí)行結(jié)束后,其分配的內(nèi)存單元繼續(xù)保留。4、register(寄存器型)——將變量對(duì)應(yīng)的儲(chǔ)存單元指定為通用寄存器,以提高程序運(yùn)行速度。缺省存儲(chǔ)種類為auto(自動(dòng))型變量C51中數(shù)據(jù)聲明的格式[類型說(shuō)明符][修飾符]標(biāo)識(shí)符[=初值]……例:unsignedchar

code

Flag=0x0f;類型說(shuō)明符修飾符標(biāo)識(shí)符初值這個(gè)定義給出的內(nèi)容是:定義一個(gè)無(wú)符號(hào)的字符型變量,該變量的名字是Flag,初值為0x0f,該變量存放在ROM空間中。說(shuō)明:如果在一個(gè)定義中,沒(méi)有修飾符,即沒(méi)有說(shuō)明存放的位置,則默認(rèn)存放在片內(nèi)RAM中,即是一個(gè)data類型的變量。例如:unsignedcharcodeFlag=0x0f;就是聲明一個(gè)無(wú)符號(hào)的char型變量Flag,并給他賦初值為0x0f;并且聲明他所在的存儲(chǔ)空間在片內(nèi)統(tǒng)一編址的ROM中。聲明中,如果沒(méi)有修飾符,則數(shù)據(jù)默認(rèn)的存儲(chǔ)空間為data型,也就是在片內(nèi)RAM中。C51的數(shù)據(jù)聲明的一般格式如下[類型說(shuō)明符][修飾符]標(biāo)識(shí)符[=初值]……C51的數(shù)據(jù)類型數(shù)據(jù)的不同格式叫做數(shù)據(jù)類型*有符號(hào)數(shù)類型可以忽略signed標(biāo)識(shí)符標(biāo)準(zhǔn)C語(yǔ)言的數(shù)據(jù)類型【存儲(chǔ)種類】

數(shù)據(jù)類型

【存儲(chǔ)類型】變量名成于大氣信達(dá)天下C51中的數(shù)據(jù)類型類型符號(hào)關(guān)鍵字所占位數(shù)數(shù)據(jù)表示范圍整型有(signed)int16-32768——32767(signed)shortint16-32768——32767(signed)longint32-2147483648~2147483647無(wú)unsignedint160——65535unsignedshortint160——65535unsignedlongint320——4294967295實(shí)型有float32-3.4e-38——3.4e+38有double32-1.7e-308——1.7e+308字符型有char8-128——127無(wú)unsignedchar80——255C語(yǔ)言中的數(shù)據(jù)類型類型符號(hào)關(guān)鍵字所占位數(shù)數(shù)據(jù)表示范圍整型有(signed)int16-32768——32767(signed)shortint16-32768——32767(signed)longint32-2147483648~2147483647無(wú)unsignedint160——65535unsignedshortint160——65535unsignedlongint320——4294967295實(shí)型有float32-3.4e-38——3.4e+38有double32-1.7e-308——1.7e+308字符型有char8-128——127無(wú)unsignedchar80——255從上面兩個(gè)表可以看出,C51中的數(shù)據(jù)類型和C語(yǔ)言中的數(shù)據(jù)類型完全一樣。C51擴(kuò)充數(shù)據(jù)類型:bit、sfr或sfr16、sbitbit型關(guān)鍵詞bit用于定義一個(gè)位變量,語(yǔ)法規(guī)則:bitbit_name

[=0或1];例如:bitdoor=0;//定義一個(gè)叫door的位變量且初值為0標(biāo)準(zhǔn)C的變量定義舉例:

inta=5; //定義一個(gè)初值為5的整形變量a

語(yǔ)法規(guī)則:intint_name[=常數(shù)];

注意:上述變量的物理地址是由編譯器分配的sfr或sfr16型關(guān)鍵詞sfr或sfr16用于定義SFR字節(jié)地址變量,語(yǔ)法規(guī)則:

sfr

sfr16sfr_name=字節(jié)地址常數(shù);51MCU中有21個(gè)SFR,如何定義與這些單元相關(guān)的變量?例如,sfrP0=0x80;//定義P0口地址80H

sfrPCON=0x87;//定義PCON地址87H

sfr16DPTR=0x82;//定義DPTR的低端地址82H注意:SFR字節(jié)地址變量的物理地址是由MCU資源決定的sbit型部分SFR具有位地址,如何定義與這些位地址相關(guān)的變量?CYACF0RS1RS0OVF1PCYACF0RS1RS0OVF1PCYACF0RS1RS0OVF1PCYACF0RS1RS0OVF1PD0^7

D7HD6HD5HD4HD3HD2HD1HD0HD0HPSWD0^6

D0^5

D0^4

D0^3

D0^2

D0^1

D0^0

絕對(duì)位地址相對(duì)位地址字節(jié)地址兩種位地址表達(dá)形式:絕對(duì)位地址、相對(duì)位地址1)將SFR的絕對(duì)位地址定義為位變量名

sbit

bit_name=位地址常數(shù);例如,sbitCY=0xD7;3)將SFR的相對(duì)位位置定義位變量名sbitbit_name=sfr_name^位位置;例如,sbitCY=PSW^7;2)將SFR的相對(duì)位地址定義為位變量名

sbit

bit_name=sfr字節(jié)地址

^位位置;例如,sbitCY=0xD0^7;關(guān)鍵詞sbit用于定義SFR位地址變量,三種定義形式:C51編譯器在頭文件“REG51.H”中定義了全部sfr/sfr16和sbit變量。用一條預(yù)處理命令#include<REG51.H>把這個(gè)頭文件包含到C51程序中,無(wú)需重新定義即可直接使用它們的名稱。應(yīng)用舉例:表1C51數(shù)據(jù)類型、長(zhǎng)度和數(shù)值范圍數(shù)據(jù)類型表示方法長(zhǎng)度數(shù)值范圍無(wú)符號(hào)字符型unsignedchar1字節(jié)0~255有符號(hào)字符型signedchar1字節(jié)-128~127無(wú)符號(hào)整型unsignedint2字節(jié)0~65535有符號(hào)整型signedint2字節(jié)-32768~32767無(wú)符號(hào)長(zhǎng)整型unsignedlong4字節(jié)0~4294967295有符號(hào)長(zhǎng)整型signedlong4字節(jié)-2147483648~2147483647浮點(diǎn)型float4字節(jié)±1.1755E-38~±3.40E+38特殊功能寄存器型sfrsfr161字節(jié)2字節(jié)0~2550~65535位類型bit、sbit1位0或1C-51的數(shù)據(jù)類型擴(kuò)充定義例:sfrP1=0x90; sfr16T2=0xCC;sbitOV=PSW^2;

sbitP10=0x90^0;或sbitP10=P1^0;類型關(guān)鍵字所占位數(shù)數(shù)的表示范圍特殊功能寄存器聲明sfr1B(8bit)0~25516位特殊功能寄存器聲明sfr162B(16bit)0~65535位變量數(shù)據(jù)聲明bit1bit0或1可尋址位(特殊功能位)聲明sbit1bit0或1對(duì)C51編譯器來(lái)說(shuō),short和int是相同類型,double和float是同一類型;低地址存高字節(jié),高地址存低字節(jié);有符號(hào)數(shù)符號(hào)位在最低字節(jié)的最高位;C-51的數(shù)據(jù)類型擴(kuò)充定義類型關(guān)鍵字所占位數(shù)數(shù)的表示范圍特殊功能寄存器聲明sfr1B(16bit)0~25516位特殊功能寄存器聲明sfr162B(32bit)0~65535位變量數(shù)據(jù)聲明bit1bit0或1可尋址位(特殊功能位)聲明sbit1bit0或1sbit是對(duì)應(yīng)可位尋址空間的一個(gè)位,可位尋址區(qū)20H~2FH或者特殊功能寄存器區(qū)0x80~0xFF。一旦用了sbitxxx=REGE^6的定義,這個(gè)sbit量就確定地址了。bit和sbit的最大區(qū)別在于,bit是定義一個(gè)變量;sbit經(jīng)常用在寄存器中的,方便對(duì)寄存器的某位進(jìn)行操作。sbit是對(duì)應(yīng)可位尋址空間的一個(gè)位,可位尋址區(qū)20H~2FH或者特殊功能寄存器區(qū)0x80~0xFF。一旦用了sbitxxx=REGE^6的定義,這個(gè)sbit量就確定地址了。bit和sbit的最大區(qū)別在于,bit是定義一個(gè)變量;sbit經(jīng)常用在寄存器中的,方便對(duì)寄存器的某位進(jìn)行操作。例如:bitbit_name;//只是申明bit_name是一個(gè)位變量名,它只能是1或者0bitdoor=0;//申明door是一個(gè)位變量,并賦初值0。

這與charabc申明abc是一個(gè)char型變量類似。bit定義了一個(gè)普通的位變量,函數(shù)可包含bit類型參數(shù),也可作為返回值。存儲(chǔ)在哪兒我們并不關(guān)心。但是:sbitCY=0xD0^7;//將位的相對(duì)地址賦給變量。sbit定義的位變量只能位于可位尋址或特殊功能寄存器中,一旦定義,其地址就不能改變啦。36用sfr16定義16位特殊功能寄存器當(dāng)16位寄存器的高8位地址緊排在低8位地址之后時(shí),就可以定義一個(gè)16位特殊功能寄存器變量。定義格式為: sfr16

特殊功能寄存器名=16位特殊功能寄存器中低8位的地址例如: sfr16DPTR=0x82;/*指定DPTR寄存器地址為0x82,其中DPL的地址為0x82,DPH的地址為0x83*/注意:這種定義適用于所有新的16位SFR,但不能用于定時(shí)/計(jì)數(shù)器T0和定時(shí)/計(jì)數(shù)器T1的定義。數(shù)組類型:數(shù)組是一組數(shù)據(jù),其中的每一個(gè)數(shù)據(jù)元素都屬于同一類型,各元素可以用數(shù)組名和下標(biāo)來(lái)唯一確定。定義格式類似于數(shù)據(jù)定義:數(shù)據(jù)類型數(shù)組名[常量表達(dá)式]多維數(shù)組的定義:數(shù)據(jù)類型數(shù)組名[常量表達(dá)式][常量表達(dá)式]

例:intxdataxx[15];charcodestr[]={“Howareyou?”};用戶RAM區(qū)用戶擴(kuò)展RAM64K位尋址區(qū)4組通用寄存區(qū)特殊功能寄存器區(qū)7FH30H2FH20H1FH00HFFH80H高128字節(jié)區(qū)低128字節(jié)區(qū)FFFFH1000H0FFFH0000H內(nèi)部ROM外部ROMEA=0只對(duì)外部ROM尋址范圍為64KBEA=1先對(duì)內(nèi)部ROM4K范圍尋址超過(guò)0FFFH時(shí)自動(dòng)尋找外部0000HFFFFH內(nèi)部RAM外部RAM80C51存儲(chǔ)器結(jié)構(gòu)組成【存儲(chǔ)種類】

數(shù)據(jù)類型【存儲(chǔ)類型】變量名51單片機(jī)的三個(gè)邏輯存儲(chǔ)空間:片內(nèi)數(shù)據(jù)存儲(chǔ)器,片外數(shù)據(jù)存儲(chǔ)器和程序存儲(chǔ)器。建立C51存儲(chǔ)類型與存儲(chǔ)空間的對(duì)應(yīng)關(guān)系data區(qū)code區(qū)xdata區(qū)bdata區(qū)pdata區(qū)idata區(qū)C51的存儲(chǔ)類型與存儲(chǔ)空間對(duì)應(yīng)關(guān)系表

SMALL系統(tǒng)COMPACT系統(tǒng)LARGE系統(tǒng)編譯模式三種編譯模式分別對(duì)應(yīng)于三種缺省存儲(chǔ)類型:【存儲(chǔ)種類】

數(shù)據(jù)類型【存儲(chǔ)類型】變量名C51編譯器可根據(jù)當(dāng)前采取的編譯模式自動(dòng)認(rèn)定默認(rèn)的存儲(chǔ)類型約定:若無(wú)特殊聲明,一般均為“SMALL編譯模式”[例]變量的存儲(chǔ)模式

#pragmasmall/*變量的存儲(chǔ)模式為Small*/chark1;/*k1存儲(chǔ)模式Small,存儲(chǔ)器類型默認(rèn)data*/intxdatam1;/*m1存儲(chǔ)模式為Small,存儲(chǔ)器類型xdata*/#pragmacompact/*變量的存儲(chǔ)模式為Compact*/chark2;/*k2存儲(chǔ)模式Compact,k2存儲(chǔ)器類型默認(rèn)pdata*/intxdatam2;/*m2存儲(chǔ)模式Compact,存儲(chǔ)器類型xdata*/intfunc1(intx1,inty1)large/*函數(shù)Large,x1和y1存儲(chǔ)器類型xdata*/{return(x1+y1);}intfunc2(intx2,inty2)/*函數(shù)默認(rèn)Small,x2和y2存儲(chǔ)器類型data*/{return(x2-y2);}4.1.4變量的存儲(chǔ)種類(屬性)變量是一種在程序執(zhí)行過(guò)程中,其數(shù)值不斷變化的量。同ANSIC一樣,C51規(guī)定變量必須先定義后使用。C51對(duì)變量的進(jìn)行定義的格式如下:[存儲(chǔ)種類]數(shù)據(jù)類型[存儲(chǔ)器類型]變量名表其中,存儲(chǔ)種類(屬性)和存儲(chǔ)器類型是可選項(xiàng)。存儲(chǔ)種類是指變量在程序執(zhí)行過(guò)程中的作用范圍。變量的存儲(chǔ)種類有四種,分別為:自動(dòng)(auto)——默認(rèn)值,變量為函數(shù)內(nèi)有效。外部(extern)——變量對(duì)所有函數(shù)有效。靜態(tài)(static)寄存器(register)——編譯系統(tǒng)自動(dòng)生成。存儲(chǔ)種類是指變量在程序執(zhí)行過(guò)程中的作用范圍。C51變量的存儲(chǔ)種類有四種,分別是自動(dòng)(auto)、外部(extern)、靜態(tài)(static)和寄存器(register)。(1).a(chǎn)uto:

使用auto定義的變量稱為自動(dòng)變量,其作用范圍在定義它的函數(shù)體或復(fù)合語(yǔ)句內(nèi)部,當(dāng)定義它的函數(shù)體或復(fù)合語(yǔ)句執(zhí)行時(shí),C51才為該變量分配內(nèi)存空間,結(jié)束時(shí)占用的內(nèi)存空間釋放。自動(dòng)變量一般分配在內(nèi)存的堆??臻g中。定義變量時(shí),如果省略存儲(chǔ)種類,則該變量默認(rèn)為自動(dòng)(auto)變量。(2).extern:使用extern定義的變量稱為外部變量。在一個(gè)函數(shù)體內(nèi),要使用一個(gè)已在該函數(shù)體外或別的程序中定義過(guò)的外部變量時(shí),該變量在該函數(shù)體內(nèi)要用extern說(shuō)明。外部變量被定義后分配固定的內(nèi)存空間,在程序整個(gè)執(zhí)行時(shí)間內(nèi)都有效,直到程序結(jié)束才釋放。(3).static:使用static定義的變量稱為靜態(tài)變量。它又分為內(nèi)部靜態(tài)變量和外部靜態(tài)變量。在函數(shù)體內(nèi)部定義的靜態(tài)變量為內(nèi)部靜態(tài)變量,它在對(duì)應(yīng)的函數(shù)體內(nèi)有效,一直存在,但在函數(shù)體外不可見(jiàn),這樣不僅使變量在定義它的函數(shù)體外被保護(hù),還可以實(shí)現(xiàn)當(dāng)離開(kāi)函數(shù)時(shí)值不被改變。外部靜態(tài)變量上在函數(shù)外部定義的靜態(tài)變量。它在程序中一直存在,但在定義的范圍之外是不可見(jiàn)的。如在多文件或多模塊處理中,外部靜態(tài)變量只在文件內(nèi)部或模塊內(nèi)部有效。外部變量與全局靜態(tài)變量的區(qū)別:(a)若程序由一個(gè)源文件構(gòu)成時(shí),全局變量與全局靜態(tài)變量沒(méi)有區(qū)別。(b)若程序由多個(gè)源文件構(gòu)成時(shí):全局靜態(tài)變量為定義該變量的源文件所獨(dú)享,對(duì)組成該程序的其它源文件是無(wú)效。(c)具有外部鏈接的靜態(tài);可以在所有源文件里調(diào)用;除了本文件,其他文件可以通過(guò)extern的方式引用;靜態(tài)全局變量的作用:(a)不必?fù)?dān)心其它源文件使用相同變量名,彼此相互獨(dú)立。(b)在某源文件中定義的靜態(tài)全局變量不能被其他源文件使用或修改。(c)只能在本文件中使用!具有內(nèi)部鏈接的靜態(tài);不允許在其他文件里調(diào)用;static全局變量與普通的全局變量有什么區(qū)別?答:1)全局變量(外部變量)的說(shuō)明之前再冠以static就構(gòu)成了靜態(tài)的全局變量。全局變量本身就是靜態(tài)存儲(chǔ)方式,靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲(chǔ)方式。這兩者在存儲(chǔ)方式上并無(wú)不同。這兩者的區(qū)別在于非靜態(tài)全局變量的作用域是整個(gè)源程序,當(dāng)一個(gè)源程序由多個(gè)源文件組成時(shí),非靜態(tài)的全局變量在各個(gè)源文件中都是有效的。而靜態(tài)全局變量則限制了其作用域,即只在定義該變量的源文件內(nèi)有效,在同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于一個(gè)源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用,因此可以避免在其它源文件中引起錯(cuò)誤。2)從以上分析可以看出,把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲(chǔ)方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,限制了它的使用范圍。3)static函數(shù)與普通函數(shù)作用域不同,僅在本文件。只在當(dāng)前源文件中使用的函數(shù)應(yīng)該說(shuō)明為內(nèi)部函數(shù)(static),內(nèi)部函數(shù)應(yīng)該在當(dāng)前源文件中說(shuō)明和定義。對(duì)于可在當(dāng)前源文件以外使用的函數(shù),應(yīng)該在一個(gè)頭文件中說(shuō)明,要使用這些函數(shù)的源文件要包含這個(gè)頭文件綜上所述:static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化一次,防止在其他文件單元中被引用;

static局部變量和普通局部變量有什么區(qū)別:static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;static函數(shù)與普通函數(shù)有什么區(qū)別:static函數(shù)在內(nèi)存中只有一份,普通函數(shù)在每個(gè)被調(diào)用中維持一份拷貝(4).register:

使用register定義的變量稱為寄存器變量。它定義的變量存放在CPU內(nèi)部的寄存器中,處理速度快,但數(shù)目少。C51編譯器編譯時(shí)能自動(dòng)識(shí)別程序中使用頻率最高的變量,并自動(dòng)將其作為寄存器變量,用戶可以無(wú)需專門聲明。C-51數(shù)據(jù)的存儲(chǔ)類型三類存儲(chǔ)器:——對(duì)應(yīng)的存儲(chǔ)器類型說(shuō)明(1)程序存儲(chǔ)器——code(2)片內(nèi)數(shù)據(jù)存儲(chǔ)器——bdata(位)、data(直接尋址128B)、idata(間接尋址256B)(3)片外數(shù)據(jù)存儲(chǔ)器——pdata(分頁(yè)尋址256B)、xdata(片外64KB)片內(nèi)數(shù)據(jù)存儲(chǔ)器分:(1)直接尋址區(qū)

(2)

間接尋址區(qū)[存儲(chǔ)種類]數(shù)據(jù)類型[存儲(chǔ)器類型]變量名表存儲(chǔ)器類型長(zhǎng)度數(shù)據(jù)范圍存儲(chǔ)空間位置描述data8位0~255直接尋址片內(nèi)數(shù)據(jù)存儲(chǔ)器低128B,訪問(wèn)速度最快bdata1位0/1可位尋址的片內(nèi)數(shù)據(jù)存儲(chǔ)器(地址20H~2FH共16B)允許位和字節(jié)混合訪問(wèn)idata8位0~255間接尋址片內(nèi)數(shù)據(jù)存儲(chǔ)器256B。允許訪問(wèn)片內(nèi)全部地址,速度較快pdata片外8位0~255用Ri訪問(wèn)片外數(shù)據(jù)存儲(chǔ)器256B,使用指令MOVX@Rn訪問(wèn),需要2個(gè)指令周期速度較慢xdata片外16位0~65535用DPTR訪問(wèn)片外數(shù)據(jù)存儲(chǔ)器64KB,使用指令MOVX@DPTR訪問(wèn),速度最慢code16位0~65535尋址程序存儲(chǔ)器區(qū)64KB,使用指令MOVC@A+DPTR訪問(wèn)例如MOVXA,@DPTR //xdata把數(shù)據(jù)指針DPTR中存的數(shù)作為地址,將該地址中的數(shù)(對(duì)應(yīng)片外的64KB存儲(chǔ)器中的某個(gè)數(shù))送入累加器A中【例】變量定義存儲(chǔ)種類和存儲(chǔ)器類型相關(guān)情況。

chardatavarl;

/*在片內(nèi)RAM低128B定義用直接尋址方式訪問(wèn)的字符型變量var1*/

intidatavar2;

/*在片內(nèi)RAM256B定義用間接尋址方式訪問(wèn)的整型變量var2*/

autounsignedlongdatavar3;

/*在片內(nèi)RAM128B定義用直接尋址方式訪問(wèn)的自動(dòng)無(wú)符號(hào)長(zhǎng)整型變量var3*/

externfloatxdatavar4;

/*在片外RAM64KB空間定義用間接尋址方式訪問(wèn)的外部實(shí)型變量var4*/

intcodevar5;

/*在ROM空間定義整型變量var5*/

unsigncharbdatavar6;

/*在片內(nèi)RAM位尋址區(qū)20H~2FH單元定義可字節(jié)處理和位處理的無(wú)符號(hào)字符型變量var6*/直接尋址方式:(片內(nèi)直接尋址data)例如:MOVA,30H;

其中,30H(無(wú)#號(hào)),是內(nèi)存的一個(gè)單元地址。功能:把30H地址單元中的內(nèi)容送累加器A。設(shè)30H單元中存放著一個(gè)數(shù)FFH,程序執(zhí)行結(jié)果A=FFH。注意:直接地址只能表示專用寄存器、內(nèi)部存儲(chǔ)器及位地址空間間接尋址方式:(片內(nèi)或片外間接尋址idata,pdata)例如MOV(或者M(jìn)OVX)A,@R1

把工作寄存器R1中數(shù)作為地址,將該地址(對(duì)應(yīng)片內(nèi)或片外的256B存儲(chǔ)器)中的數(shù)送入累加器A中。一個(gè)變量的存儲(chǔ)器模式確定了未聲明存儲(chǔ)器類型的變量在內(nèi)存中的地址空間。在SMALL模式下,該變量在80C51單片機(jī)的內(nèi)部RAM中;在COMPACT和LARGE模式下,該變量在80C51單片機(jī)的外部RAM中。建議在編寫源程序時(shí),把存儲(chǔ)模式設(shè)定為SMALL(默認(rèn),即對(duì)存儲(chǔ)模式不作聲明),再在程序中把xdata、pdata和idata等類型變量進(jìn)行專門聲明。C51編譯器允許采用三種存儲(chǔ)模式:小編譯模式SMALL、緊湊編譯模式COMPACT、大編譯模式LARGE。C-51數(shù)據(jù)的存儲(chǔ)模式存儲(chǔ)器模式存儲(chǔ)模式是指函數(shù)自變量、自動(dòng)變量和沒(méi)有明確規(guī)定存儲(chǔ)類型的變量的默認(rèn)存儲(chǔ)器類型。通過(guò)在命令行中增加控制命令可以指定他們的存儲(chǔ)器類型。主要三種模式:COMPACTdataLARGESMALLxdatapdata在程序中變量的存儲(chǔ)模式的指定通過(guò)#pragma預(yù)處理命令來(lái)實(shí)現(xiàn)。函數(shù)的存儲(chǔ)模式可通過(guò)在函數(shù)定義時(shí)后面帶存儲(chǔ)模式說(shuō)明。如果沒(méi)有指定,則系統(tǒng)都隱含為SMALL模式?!纠孔兞康拇鎯?chǔ)模式。#pragmasmall/*變量的存儲(chǔ)模式為SMALL*/chark1;intxdatam1;#pragmacompact/*變量的存儲(chǔ)模式為compact*/chark2;intxdatam2;intfunc1(intx1,inty1)large/*函數(shù)的存儲(chǔ)模式為L(zhǎng)ARGE*/{return(x1+y1);}intfunc2(intx2,inty2)/*函數(shù)的存儲(chǔ)模式隱含為SMALL*/{return(x2-y2);}

程序編譯時(shí),k1變量存儲(chǔ)器類型為data,k2變量存儲(chǔ)器類型為pdata,而m1和m2由于定義時(shí)帶了存儲(chǔ)器類型xdata,因而它們?yōu)閤data型;函數(shù)func1的形參x1和y1的存儲(chǔ)器類型為xdata型,而函數(shù)func2由于沒(méi)有指明存儲(chǔ)模式,隱含為SMALL模式,形參x2和y2的存儲(chǔ)器類型為data。成于大氣信達(dá)天下C51的基本語(yǔ)句與標(biāo)準(zhǔn)C語(yǔ)言基本相同:

if

選擇語(yǔ)言

switch/case

多分支選擇語(yǔ)言

while

循環(huán)語(yǔ)言

do-while

循環(huán)語(yǔ)言

for

循環(huán)語(yǔ)言指針類型:在C語(yǔ)言中為了能夠?qū)崿F(xiàn)直接對(duì)內(nèi)存單元進(jìn)行操作,引入了指針類型的數(shù)據(jù)。指針是專門用來(lái)確定其它數(shù)據(jù)類型的地址的。因此,一個(gè)變量的地址被稱為該變量的指針。指針變量的定義格式為:數(shù)據(jù)類型[存儲(chǔ)器類型]*標(biāo)識(shí)符例如:“&a”為變量a的地址;“*p”為指針變量所指向的變量。其中,“標(biāo)識(shí)符”為所定義的指針變量名;“數(shù)據(jù)類型”說(shuō)明該指針變量所指向的變量的類型。指針變量的引用:指針有關(guān)的運(yùn)算符有兩個(gè):地址運(yùn)算符“&”和間接訪問(wèn)運(yùn)算符“*”。用typedef重新定義數(shù)據(jù)類型的名稱在C語(yǔ)言中為了簡(jiǎn)化輸入,可以根據(jù)自己的需要,對(duì)前面介紹的數(shù)據(jù)類型重新定義。格式為:例如:typedefunsingedcharuchar ;即在之后的程序中都可以用uchar代表unsingedchar。

typedefunsingedlongulong ;即在之后的程序中都可以用ulong代表unsingedlongtypedef已有數(shù)據(jù)類型新的數(shù)據(jù)類型對(duì)data區(qū)的尋址是最快的,所以應(yīng)該把使用頻率高的變量放在data區(qū),由于空間有限,必須注意使用data區(qū),data區(qū)除了包含程序變量外,還包含了堆棧和寄存器組data區(qū)。在SMALL存儲(chǔ)模式下,未說(shuō)明存儲(chǔ)器類型時(shí),變量默認(rèn)被定位在data區(qū)。如果在變量定義時(shí)省略了存儲(chǔ)器類型標(biāo)識(shí)符,C51編譯器會(huì)選擇默認(rèn)的存儲(chǔ)器類型。默認(rèn)的存儲(chǔ)器類型由SMALL、COMPACT和LARGE存儲(chǔ)模式指令決定。1)data區(qū)當(dāng)在DATA區(qū)的位尋址區(qū)定義變量,這個(gè)變量就可進(jìn)行位尋址,并且聲明位變量。這對(duì)狀態(tài)寄存器來(lái)說(shuō)十分有用,因?yàn)樗梢詥为?dú)使用變量的每一位,而不一定要用位變量名引用位變量。idata區(qū)也可以存放使用比較頻繁的變量,使用寄存器作為指針進(jìn)行尋址。在寄存器中設(shè)置8位地址進(jìn)行間接尋址,與外部存儲(chǔ)器尋址比較,它的指令執(zhí)行周期和代碼長(zhǎng)度都比較短。2)bdata區(qū)3)idata區(qū)在這兩個(gè)區(qū)聲明變量和在其他區(qū)的語(yǔ)法是一樣的,pdata區(qū)只有256B,而xdata區(qū)可達(dá)65536Bcode區(qū)即80C51的程序代碼區(qū),所以代碼區(qū)的數(shù)據(jù)是不可改變的,80C51的代碼區(qū)不可重寫。一般代碼區(qū)中可存放數(shù)據(jù)表,跳轉(zhuǎn)向量和狀態(tài)表4)pdata和xdata區(qū)5)code區(qū)存儲(chǔ)器模式聲明形式:voidfun(void)small{}SMALL所有變量都默認(rèn)的位于51內(nèi)部數(shù)據(jù)存儲(chǔ)器,這和使用data指定存儲(chǔ)器類型的方式一樣COMPACT所有變量都唄默認(rèn)為在外部數(shù)據(jù)存儲(chǔ)器的頁(yè)內(nèi),這和使用pdata指定存儲(chǔ)器類型是一樣的。LARGE所有變量都默認(rèn)為位于外部數(shù)據(jù)存儲(chǔ)器,與使用xdata指定存儲(chǔ)器類型是一樣的例:數(shù)據(jù)類型存儲(chǔ)類型變量chardatavar1;bitdataflags;unsignedcharxdatavextor[10];4.1.6.使用C51擴(kuò)展關(guān)鍵字_at_

使用_at_對(duì)指定的存儲(chǔ)器空間的絕對(duì)地址進(jìn)行訪問(wèn),一般格式如下:

[存儲(chǔ)器類型]數(shù)據(jù)類型說(shuō)明符變量名_at_地址常數(shù);其中,存儲(chǔ)器類型為data、bdata、idata、pdata等C51能識(shí)別的數(shù)據(jù)類型,如省略則按存儲(chǔ)模式規(guī)定的默認(rèn)存儲(chǔ)器類型確定變量的存儲(chǔ)器區(qū)域;數(shù)據(jù)類型為C51支持的數(shù)據(jù)類型。地址常數(shù)用于指定變量的絕對(duì)地址,必須位于有效的存儲(chǔ)器空間之內(nèi);使用_at_定義的變量必須為全局變量?!纠客ㄟ^(guò)_at_實(shí)現(xiàn)絕對(duì)地址的訪問(wèn)。#defineucharunsignedchar/*定義符號(hào)uchar為數(shù)據(jù)類型符unsignedchar*/#defineuintunsignedint/*定義符號(hào)uint為數(shù)據(jù)類型符unsignedint*/voidmain(void){dataucharx1_at_0x40;/*在data區(qū)中定義字節(jié)變量

x1,它的地址為40H*/xdatauintx2_at_0x2000;/*在xdata區(qū)中定義字變量

x2,它的地址為2000H*/x1=0xff;x2=0x1234;......while(1);}運(yùn)算符就是完成某種特定運(yùn)算的符號(hào)。C51的數(shù)據(jù)運(yùn)算操作與標(biāo)準(zhǔn)C語(yǔ)言基本相同,具有十分豐富的運(yùn)算符,對(duì)數(shù)據(jù)有很強(qiáng)的表達(dá)能力:運(yùn)算符按其表達(dá)式中與運(yùn)算符的關(guān)系(含有運(yùn)算符的數(shù)量)可分為單目運(yùn)算符、雙目運(yùn)算符和三目運(yùn)算符。三、C51的運(yùn)算符和表達(dá)式1、C-51的運(yùn)算符成于大氣信達(dá)天下C51中的運(yùn)算符與C語(yǔ)言基本相同:+,-,*,/

,%

(加減乘除求余)>,>=,<,<=

(大于大于等于小于小于 等于)==,!=

(測(cè)試等于測(cè)試不等于)&&,||,!

(邏輯與邏輯或邏輯非)>><<

(位右移位左移)&,|

(按位與按位或)^,~

(按位異或按位取反)算術(shù)運(yùn)算符運(yùn)算符范例說(shuō)明+A+b加或取正值運(yùn)算符-A-b減或取負(fù)值運(yùn)算符*A*b乘運(yùn)算符/A/b除運(yùn)算符%A%b模(取余)運(yùn)算符,如8%5=3++A++等同于A=A+1--A--等同于A=A-1賦值運(yùn)算符使用“=”的賦值語(yǔ)句格式如下:注意“==”與“=”兩個(gè)運(yùn)算符和賦值運(yùn)算符“=”結(jié)合后使用的區(qū)別。變量=表達(dá)式;注意“==”與“=”兩個(gè)運(yùn)算符和賦值運(yùn)算符“=”結(jié)合后使用的區(qū)別。例1:

a=1; b=++a;其運(yùn)算過(guò)程是a加1變?yōu)?,然后賦值給b,即:b=2,a=2。例2:

a=1; b=a++;其運(yùn)算過(guò)程是賦值給b,然后a加1變?yōu)?,即:b=1,a=2。關(guān)系運(yùn)算符C51中有6種關(guān)系運(yùn)算符:>大于<小于>=大于等于<=小于等于==測(cè)試等于!=測(cè)試不等于關(guān)系表達(dá)式的值是真”和“假”,用“1”和“0”表示。邏輯運(yùn)算符邏輯與:條件式1&&

條件式2。邏輯或:條件式1||

條件式2。邏輯非:!條件式。位運(yùn)算符C51中共有6種位運(yùn)算符:&按位與|按位或^按位異或~按位取反<<左移>>右移復(fù)合運(yùn)算符就是在賦值運(yùn)算符“=”的前面加上其他運(yùn)算符。運(yùn)算符范例說(shuō)明+=加法賦值 A+=b等同于A=A+b-=減法賦值 *=乘法賦值 /=除法賦值 %=取模賦值<<=左移位賦值>>=右移位賦值&=邏輯與賦值|=邏輯或賦值^=邏輯異或賦值~=邏輯非賦值【例】如何點(diǎn)亮發(fā)光二極管(本程序的功能是:讓奇數(shù)個(gè)發(fā)光二極管一亮一滅不停的在閃爍)#include<AT89X52.H>#defineuintunsignedint#defineucharunsignedcharsbitD1=P1^0;sbitD3=P1^2;sbitD5=P1^4;sbitD7=P1^6;voiddelay();voidmain(){ while(1) { D1=0; D3=0; D5=0; D7=0; delay(10); D1=1; D3=1; D5=1; D7=1; delay(10); }}voiddelay(){ uintx,y; for(x=10;x>0;x--) for(y=2000;y>0;y--);}C51中絕對(duì)地址的訪問(wèn)

C51中絕對(duì)地址的訪問(wèn)有三種方法:使用C51運(yùn)行庫(kù)中預(yù)定義宏,通過(guò)指針訪問(wèn),使用C51擴(kuò)展關(guān)鍵字_at_。1.使用C51運(yùn)行庫(kù)中預(yù)定義宏

C51編譯器提供了一組宏定義來(lái)對(duì)MCS-51單片機(jī)的地址空間進(jìn)行絕對(duì)尋址。規(guī)定只能以無(wú)符號(hào)數(shù)方式訪問(wèn)。在包含頭文件absacc.h的前提下,可以使用預(yù)處理命令#define指令定義不同存儲(chǔ)空間各個(gè)變量的絕對(duì)地址。形式為:

#include<absacc.h>訪問(wèn)形式:預(yù)定義宏名[地址]函數(shù)原型定義:

#define宏名((數(shù)據(jù)類型volatile*)0x存儲(chǔ)單元的絕對(duì)地址)預(yù)定義宏名:

CBYTE——code區(qū)(字節(jié))

DBYTE——data區(qū)(字節(jié))

PBYTE——pdata區(qū)(字節(jié))

XBYTE——xdata區(qū)(字節(jié))

CWORD——code區(qū)(字)

DWORD——data區(qū)(字)

PWORD——pdata區(qū)(字)

XWORD——xdata區(qū)(字)

預(yù)定義宏名表示絕對(duì)地址所處的存儲(chǔ)空間和數(shù)據(jù)長(zhǎng)度。[例]絕對(duì)地址對(duì)存儲(chǔ)單元的訪問(wèn)

#include<absacc.h>/*將絕對(duì)地址頭文件包含在文件中*/#include<reg52.h>/*將寄存器頭文件包含在文件中*/#defineucharunsignedchar/*定義符號(hào)uchar為數(shù)據(jù)類型符unsignedchar*/#defineuintunsignedint/*定義符號(hào)uint為數(shù)據(jù)類型符unsignedint*/voidmain(void){ucharvar1;uintvar2;var1=XBYTE[0x0005];/*訪問(wèn)片外RAM的0005字節(jié)單元*/var2=XWORD[0x0002];/*訪問(wèn)片外RAM的0002字單元*/......while(1);}2.使用指針采用指針的方法,可實(shí)現(xiàn)在C51程序中對(duì)任意指定的存儲(chǔ)器地址進(jìn)行操作。ucharidataivar1;ucharxdata*xdp;/*定義一個(gè)指向xdata存儲(chǔ)器空間的指針*/chardata*dp;/*定義一個(gè)指向DATA存儲(chǔ)器空間的指針*/ucharidata*idp;/*定義一個(gè)指向idata存儲(chǔ)器空間的指針*/xdp=0x1000;/*xdata指針賦值,指向xdata存儲(chǔ)器地址1000H處*/*xdp=0x5A;/*將數(shù)據(jù)5AH送到xdata的1000H單元*/dp=0x61; /*DATA指針賦值,指向DATA存儲(chǔ)器地址61H處*/*dp=0x23; /*將數(shù)據(jù)23H送到DATA的61H單元*/idp=&ivar1; /*idp指向idata區(qū)變量ivar1*/*idp=0x16; /*等價(jià)于ivar1=0x16*/指針與地址運(yùn)算符:

*(指針運(yùn)算符),&(取地址運(yùn)算符)

功能:

“*”放在指針變量前面,實(shí)現(xiàn)訪問(wèn)以指針變量的內(nèi)容為地址所指向的存儲(chǔ)單元。例如:指針變量p中的地址為2000H,則*p所訪問(wèn)的是地址為2000H的存儲(chǔ)單元,x=*p,實(shí)現(xiàn)把地址為2000H的存儲(chǔ)單元的內(nèi)容送給變量x?!?”放在變量的前面,通過(guò)它取得變量的地址,變量的地址通常送給指針變量。例如:設(shè)變量x的內(nèi)容為12H,地址為2000H,則&x的值為2000H,如有一指針變量p,則通常用p=&x,實(shí)現(xiàn)將x變量的地址送給指針變量p,指針變量p指向變量x,以后可以通過(guò)*p訪問(wèn)變量x。3.使用C51擴(kuò)展關(guān)鍵字_at_使用_at_對(duì)指定的存儲(chǔ)器空間的絕對(duì)地址進(jìn)行定位,一般格式如下:

[存儲(chǔ)器類型]數(shù)據(jù)類型標(biāo)識(shí)符_at_常數(shù)ucharxdataxram[0x8000]_at_0x0000;/*在外部RAM空間0000H處定義了一個(gè)一維數(shù)組變量xram,數(shù)組的元素個(gè)數(shù)為32768(0x8000)*/例如使用_at_定義的變量只能為全局變量。使用C51擴(kuò)展關(guān)鍵字_at_

使用_at_對(duì)指定的存儲(chǔ)器空間對(duì)地址進(jìn)行訪問(wèn),一般格式如下:

[存儲(chǔ)器類型]數(shù)據(jù)類型說(shuō)明符變量名_at_地址常數(shù);

其中,存儲(chǔ)器類型為等C51能識(shí)別的數(shù)據(jù)類型,如省略則按存儲(chǔ)器規(guī)定的默認(rèn)存儲(chǔ)器類型確定變量的存儲(chǔ)區(qū)域;數(shù)據(jù)類型為C51支持的數(shù)據(jù)類型;

地址常數(shù)用于指定變量的絕對(duì)地址,必須位于有效的存儲(chǔ)空間之內(nèi);使用_at_定義的變量必須為全局變量【例】通過(guò)_at_實(shí)現(xiàn)絕對(duì)地址的訪問(wèn)。

#defineucharunsingedchar//定義符號(hào)uchar為數(shù)據(jù)類型符unsignedchar

#defineuintunsignedint//定義符號(hào)uint為數(shù)據(jù)類型符unsignedint

voidmain(void){

dataucharx1_at_0x40;//在data區(qū)中定義字節(jié)變量,它的地址為40H

xdatauintx2_at_0x2000;//在xdata區(qū)中定義字變量,它的地址為2000H

x1=0xff;

x2=0x1234;

……

while(1);

}與一般C語(yǔ)言的結(jié)構(gòu)相同,以main()函數(shù)為程序人口,程序體中包含若干語(yǔ)句還可以包含若干函數(shù)。C-51函數(shù)的一般格式

類型函數(shù)名(參數(shù)表)

{

數(shù)據(jù)說(shuō)明部分語(yǔ)句執(zhí)行部分

}§4-4C51程序設(shè)計(jì)及應(yīng)用4.4.1C51的程序結(jié)構(gòu)C語(yǔ)言的結(jié)構(gòu)化特征非常明顯:C語(yǔ)言源程序總是由若干個(gè)函數(shù)組成,以main()函數(shù)為程序入口,程序體中包含若干語(yǔ)句還可以包含若干函數(shù)調(diào)用。C語(yǔ)言中的函數(shù)很多可以重復(fù)利用,形成了函數(shù)庫(kù),程序員只需按照要求調(diào)用,極大地節(jié)省了開(kāi)發(fā)者的時(shí)間和精力,大大降低了出錯(cuò)幾率?!?-4C51程序設(shè)計(jì)及應(yīng)用4.4.1C51的程序結(jié)構(gòu)從程序控制語(yǔ)句以及函數(shù)的使用上來(lái)講,C51與標(biāo)準(zhǔn)C幾乎沒(méi)有什么明顯的區(qū)別。只是在函數(shù)的使用上,由于單片機(jī)系統(tǒng)的資源有限,它的編譯系統(tǒng)不允許太多的程序嵌套。在前面已多次使用過(guò)以“#”號(hào)開(kāi)頭的預(yù)處理命令。如包含命令#include,宏定義命令#define等。凡是以“#”開(kāi)頭的均為預(yù)處理命令。在源程序中這些命令都放在函數(shù)之外,而且一般都放在源文件的前面,它們稱為預(yù)處理部分。

所謂預(yù)處理是指在進(jìn)行編譯的第一遍掃描(詞法掃描和語(yǔ)法分析)之前所作的工作。預(yù)處理是C語(yǔ)言的一個(gè)重要功能,它由預(yù)處理程序負(fù)責(zé)完成。當(dāng)對(duì)一個(gè)源文件進(jìn)行編譯時(shí),系統(tǒng)將自動(dòng)引用預(yù)處理程序?qū)υ闯绦蛑械念A(yù)處理部分作處理,處理完畢自動(dòng)進(jìn)入對(duì)源程序的編譯。C語(yǔ)言提供了多種預(yù)處理功能,如宏定義、文件包含、條件編譯等。合理地使用預(yù)處理功能編寫的程序便于閱讀、修改、移植和調(diào)試,也有利于模塊化程序設(shè)計(jì)。本章介紹常用的幾種預(yù)處理功能。4.4.2文件預(yù)處理與頭文件一、宏定義

在C語(yǔ)言源程序中允許用一個(gè)標(biāo)識(shí)符來(lái)表示一個(gè)字符串,稱為“宏”。被定義為“宏”的標(biāo)識(shí)符稱為“宏名”。在編譯預(yù)處理時(shí),對(duì)程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開(kāi)”。宏定義是由源程序中的宏定義命令完成的。宏代換是由預(yù)處理程序自動(dòng)完成的。宏定義的一般形式為:

#define標(biāo)識(shí)符字符串“define”為宏定義命令。“標(biāo)識(shí)符”為所定義的宏名。“字符串”可以是常數(shù)、表達(dá)式、或含有參數(shù)的表達(dá)式、格式串等。在程序中多次使用宏,可以簡(jiǎn)化源程序的輸入。與使用函數(shù)相比,會(huì)占用較多內(nèi)存,但執(zhí)行速度快。例如:

#defineM(y*y+3*y)二、文件包含命令

文件包含是C預(yù)處理程序的另一個(gè)重要功能。文件包含是用指定文件的全部?jī)?nèi)容替換該預(yù)處理命令行。即一個(gè)程序文件將另一個(gè)指定文件的內(nèi)容完全包含進(jìn)來(lái)。在程序設(shè)計(jì)中,文件包含是很有用的。一個(gè)大的程序可以分為多個(gè)模塊,由多個(gè)程序員分別編程。有些公用的符號(hào)常量或宏定義等可單獨(dú)組成一個(gè)文件,在其它文件的開(kāi)頭用包含命令包含該文件即可使用。這樣,可避免在每個(gè)文件開(kāi)頭都去書寫那些公用量,從而節(jié)省時(shí)間,并減少出錯(cuò)。

#include"文件名"

或: #include<文件名>

。文件包含的對(duì)象最為常見(jiàn)的是頭文件(擴(kuò)展名.h)。在前面我們已多次用此命令包含過(guò)庫(kù)函數(shù)的頭文件。文件包含命令行的一般形式為:C系統(tǒng)提供了豐富的系統(tǒng)文件,稱為庫(kù)文件。C51的強(qiáng)大功能及其高效率的重要體現(xiàn)之一在于,其提供了豐富的可直接調(diào)用的庫(kù)函數(shù)。使用庫(kù)函數(shù)使程序代碼簡(jiǎn)單、結(jié)構(gòu)清晰、易于調(diào)試和維護(hù),

C的庫(kù)文件分為兩類,一類是擴(kuò)展名為“.h”的文件,稱為頭文件,在前面的包含命令中我們已多次使用過(guò)。在“.h”文件中包含了常量定義、類型定義、宏定義、函數(shù)原型以及各種編譯選擇設(shè)置等信息。另一類是函數(shù)庫(kù),包括了各種函數(shù)的目標(biāo)代碼,供用戶在程序中調(diào)用。為了使用51單片機(jī)的內(nèi)部資源,如定時(shí)器、中斷、I/O等,需要將說(shuō)明相應(yīng)的功能寄存器的頭文件加載在程序中。如前面所使用的reg51.h等。因此,C51系列頭文件集中體現(xiàn)了各系列芯片的不同功能。通常在程序中調(diào)用一個(gè)庫(kù)函數(shù)時(shí),要在調(diào)用之前包含該函數(shù)原型所在的".h"文件。部分庫(kù)函數(shù)不適合單片機(jī)處理系統(tǒng),因此被排除在外,如字符屏幕和圖形函數(shù)。部分庫(kù)函數(shù)的定義與標(biāo)準(zhǔn)C有很大不同,如printf和scanf函數(shù),在C51中用于串口數(shù)據(jù)的發(fā)送和接收。C51與標(biāo)準(zhǔn)ANSIC庫(kù)函數(shù)的不同:reg51.h,reg52.h——定義特殊功能寄存器和位寄存器;math.h——數(shù)學(xué)函數(shù)。本分類給出了各種數(shù)學(xué)計(jì)算函數(shù)stdio.h——輸入輸出函數(shù)。該分類用于處理包括文件、控制臺(tái)等各種輸入輸出設(shè)備,各種函數(shù)以“流”的方式實(shí)現(xiàn)intrins.h——內(nèi)部函數(shù)ctype.h——字符處理函數(shù)。本類別函數(shù)用于對(duì)單個(gè)字符進(jìn)行處理,包括字符的類別測(cè)試和字符的大小寫轉(zhuǎn)換stdlib.h——實(shí)用工具函數(shù)。string.h——字符串處理。本分類的函數(shù)用于對(duì)字符串進(jìn)行合并、比較等操作;absacc.h——絕對(duì)地址訪問(wèn)函數(shù)。C51常用庫(kù)函數(shù):93使用頭文件,再直接用位名稱 #include<STC12C5A.h> TR0=1;EA=1;TF0=0;//在文件中已定義了TR0、EA、 TF0……等位使用頭文件及sbit定義符,用于無(wú)位名稱的可位尋址位。 #include<STC12C5A.h> sbit P1_0=P1^0; sbit a_7=ACC^7;

由于在51內(nèi)核單片機(jī)產(chǎn)品中特殊功能寄存器的數(shù)量和類型不盡相同,C51建立了一個(gè)頭文件reg51.h(增強(qiáng)型為reg52.h),STC系列單片機(jī)的頭文件有STC90.h、STC10.h、STC11.h、STC12C5A.h、STC12C52.h、STC12C54.h、STC12C56.h、STC15.h、STC89.h等。94 在這些頭文件中對(duì)相應(yīng)系列的所有特殊功能寄存器進(jìn)行了sfr定義,對(duì)特殊功能寄存器中有位名稱并且可位尋址位進(jìn)行了sbit定義,只要使用了#include<STC12C5A.h>或#include<reg52.h>等包含語(yǔ)句,就可以直接引用該文件中已經(jīng)定義過(guò)的特殊功能寄存器名及位名稱。注意:在引用特殊功能寄存器名及位名稱時(shí)必須大寫。我們也可以用自己喜歡的名字寫定義文件,使用時(shí)只要用包含語(yǔ)句#include“****.h”就可以直接引用已定義的特殊功能寄存器名和位名稱。四、C-51的基本語(yǔ)句與標(biāo)準(zhǔn)C語(yǔ)言基本相同:if選擇語(yǔ)言switch/case

多分支選擇語(yǔ)言while

循環(huán)語(yǔ)言

do-while

循環(huán)語(yǔ)言for

循環(huán)語(yǔ)言1)第一種形式為基本形式:if

if(表達(dá)式)語(yǔ)句其語(yǔ)義是:如果表達(dá)式的值為真,則執(zhí)行其后的語(yǔ)句,否則不執(zhí)行該語(yǔ)句。其過(guò)程可表示為下圖。1、if語(yǔ)句的三種形式2)第二種形式為:if-elseif(表達(dá)式)

語(yǔ)句1;

else

語(yǔ)句2;其語(yǔ)義是:如果表達(dá)式的值為真,則執(zhí)行語(yǔ)句1,否則執(zhí)行語(yǔ)句2。例如:if(x>y){max=x;}else{max=y;}

本形式相當(dāng)于雙分支選擇結(jié)構(gòu)。3.當(dāng)有多個(gè)分支選擇時(shí),可采用if-else-if語(yǔ)句,其一般形式為:if(表達(dá)式1)

語(yǔ)句1;

elseif(表達(dá)式2)

語(yǔ)句2;

elseif(表達(dá)式3)

語(yǔ)句3;

elseif(表達(dá)式m)

語(yǔ)句m;

else

語(yǔ)句n;其語(yǔ)義是:依次判斷表達(dá)式的值,當(dāng)出現(xiàn)某個(gè)值為真時(shí),則執(zhí)行其對(duì)應(yīng)的語(yǔ)句。然后跳到整個(gè)if語(yǔ)句之外繼續(xù)執(zhí)行程序。如果所有的表達(dá)式均為假,則執(zhí)行語(yǔ)句n。然后繼續(xù)執(zhí)行后續(xù)程序?!纠?.5】例如:if(x>100){y=1;}elseif(x>50){y=2;}elseif(x>30){y=3;}elseif(x>20){y=4;}else{y=5;}99【例5.5】二、switch語(yǔ)句C語(yǔ)言還提供了另一種用于多分支選擇的switch語(yǔ)句,其一般形式為:

switch(表達(dá)式){case常量表達(dá)式1:語(yǔ)句1;case常量表達(dá)式2:語(yǔ)句2;…case常量表達(dá)式n:語(yǔ)句n;default:語(yǔ)句n+1;}其語(yǔ)義是:計(jì)算表達(dá)式的值。并逐個(gè)與其后的常量表達(dá)式值相比較,當(dāng)表達(dá)式的值與某個(gè)常量表達(dá)式的值相等時(shí),即執(zhí)行其后的語(yǔ)句,然后不再進(jìn)行判斷,繼續(xù)執(zhí)行后面所有case后的語(yǔ)句。如表達(dá)式的值與所有case后的常量表達(dá)式均不相同時(shí),則執(zhí)行default后的語(yǔ)句。例如:……switch(keynum){ case1: key1();break; //如果keynum為1,則執(zhí)行函數(shù)key1() case2: key2();break; //如果keynum為2,則執(zhí)行函數(shù)key2() case3: key3();break; //如果keynum為3,則執(zhí)行函數(shù)key3() case4: key4();break; //如果keynum為4,則執(zhí)行函數(shù)key4()

……

default:gotoinput}while語(yǔ)句的一般形式為:

while(表達(dá)式)語(yǔ)句其中表達(dá)式是循環(huán)條件,語(yǔ)句為循環(huán)體。

while語(yǔ)句的語(yǔ)義是:計(jì)算表達(dá)式的值,當(dāng)值為真(非0)時(shí),執(zhí)行循環(huán)體語(yǔ)句。其執(zhí)行過(guò)程可用下圖表示。三、while語(yǔ)句 例如:

while((P1&0x80)==0){}do-while語(yǔ)句的一般形式為:

do

語(yǔ)句

while(表達(dá)式);這個(gè)循環(huán)與while循環(huán)的不同在于:它先執(zhí)行循環(huán)中的語(yǔ)句,然后再判斷表達(dá)式是否為真,如果為真則繼續(xù)循環(huán);如果為假,則終止循環(huán)。因此,do-while循環(huán)至少要執(zhí)行一次循環(huán)語(yǔ)句。其執(zhí)行過(guò)程可用下圖表示。四、do-while語(yǔ)句

例:

do { sum+=sample[n];

n++;

}while(n<10);在C語(yǔ)言中,for語(yǔ)句使用最為靈活,它完全可以取代while語(yǔ)句。它的一般形式為:

for(表達(dá)式1;表達(dá)式2;表達(dá)式3)語(yǔ)句它的執(zhí)行過(guò)程如下:先求解表達(dá)式1。求解表達(dá)式2,若其值為真(非0),則執(zhí)行for語(yǔ)句中指定的內(nèi)嵌語(yǔ)句,然后執(zhí)行下面第3)步;若其值為假(0),則結(jié)束循環(huán),轉(zhuǎn)到第5)步。求解表達(dá)式3。轉(zhuǎn)回上面第2)步繼續(xù)執(zhí)行。循環(huán)結(jié)束,執(zhí)行for語(yǔ)句下面的一個(gè)語(yǔ)句。其執(zhí)行過(guò)程可用下圖表示。五、for語(yǔ)句for語(yǔ)句最簡(jiǎn)單的應(yīng)用形式也是最容易理解的形式如下:for(循環(huán)變量賦初值;循環(huán)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論