單片機(jī)C語言課件_第1頁
單片機(jī)C語言課件_第2頁
單片機(jī)C語言課件_第3頁
單片機(jī)C語言課件_第4頁
單片機(jī)C語言課件_第5頁
已閱讀5頁,還剩167頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、 單片機(jī)C語言及程序設(shè)計(jì)1.1 C51概述1.2 C51數(shù)據(jù)類型及存儲(chǔ)1.3 C51變量的定義及數(shù)據(jù)存儲(chǔ)區(qū)域1.4 C51位變量的定義1.5 C51特殊功能寄存器的定義1.6 C51指令的定義1.7 C51的輸入/輸出1.8 C51函數(shù)的定義1.9 C51與匯編語言混合編程1.10 C51集成開發(fā)軟件Keil C目 錄本章主要討論C51變量的定義和函數(shù)的定義,以及Keil C軟件的使用等。本章內(nèi)容的安排,認(rèn)為讀者已經(jīng)學(xué)習(xí)過C語言,具有C語言的基本知識,因此,本章內(nèi)容完全是結(jié)合單片機(jī)來講解,也就是補(bǔ)充C語言在單片機(jī)方面的概念、數(shù)據(jù)定義和函數(shù)定義等。通過本章學(xué)習(xí),使讀者能夠比較順利地編寫C51程序

2、。 1.1 C51概述主要內(nèi)容1.1.1 C語言編程的優(yōu)勢1.1.2 C51與ANSI C的區(qū)別1.1.3 C51擴(kuò)展的關(guān)鍵字1.1 C51概述學(xué)習(xí)單片機(jī)C語言的必要性隨著單片機(jī)性能的不斷提高,C語言編譯調(diào)試工具的不斷完善,以及現(xiàn)在對單片機(jī)產(chǎn)品輔助功能的要求、對開發(fā)周期不斷縮短的要求,使得越來越多的單片機(jī)編程人員轉(zhuǎn)向使用C語言,因此有必要在單片機(jī)課程中講授“單片機(jī)C語言”。 “C51”概念:為了與ANSI C區(qū)別,把“單片機(jī)C語言”稱為“C51”,也稱為“Keil C”。 1.1.1 C語言編程的優(yōu)勢在編程方面,使用C51較匯編語言有諸多優(yōu)勢:1)編程容易 2)容易實(shí)現(xiàn)復(fù)雜的數(shù)值計(jì)算3)容易閱

3、讀與交流4)容易調(diào)試與維護(hù)程序5)容易實(shí)現(xiàn)模塊化開發(fā) 6)程序可移植性好 1.1.2 C語言與ANSI 的區(qū)別用匯編語言編寫單片機(jī)程序時(shí),必須要考慮其存儲(chǔ)器的結(jié)構(gòu),尤其要考慮其片內(nèi)數(shù)據(jù)存儲(chǔ)器、特殊功能寄存器是否正確合理的使用,以及按照實(shí)際地址端口數(shù)據(jù)的處理。用C51編寫程序,雖然不像匯編語言那樣需要具體地組織、分配存儲(chǔ)器資源,但是C51對數(shù)據(jù)類型和變量的定義,必須要與單片機(jī)的存儲(chǔ)結(jié)構(gòu)相關(guān)聯(lián),否則編譯器不能正確地映射定位。 用C51編寫單片機(jī)程序,與用ANSI C編寫程序的不同之處是,需要根據(jù)單片機(jī)存儲(chǔ)器結(jié)構(gòu)及內(nèi)部資源,定義相應(yīng)的數(shù)據(jù)類型和變量。其它的語法規(guī)定、程序結(jié)構(gòu)及程序設(shè)計(jì)方法,都與ANS

4、I C相同。所以本章主要介紹C51各種變量的定義、指針定義、函數(shù)定義和混合編程。 1.1.3 C51擴(kuò)展的關(guān)鍵字由于單片機(jī)在結(jié)構(gòu)及編程上的特殊要求,C51有自己的特殊關(guān)鍵字,稱之為C51擴(kuò)展的關(guān)鍵字,下面給出常用的C51擴(kuò)展的關(guān)鍵字。_at_bdatabit codedataidata interruptpdatareentrant sbitsfrsfr16usingvolatilexdata這些關(guān)鍵字在后面會(huì)陸續(xù)接觸到,此處先不給出它們的含義。 1.2 C51數(shù)據(jù)類型及存儲(chǔ)主要內(nèi)容1.2.1 C51的數(shù)據(jù)類型1.2.2 C51數(shù)據(jù)的存儲(chǔ)表4-1 C51數(shù)據(jù)類型、長度和數(shù)值范圍數(shù)據(jù)類型表示方法

5、長 度數(shù) 值 范 圍無符號字符型unsigned char1字節(jié)0255有符號字符型signed char1字節(jié)-128127無符號整型unsigned int2字節(jié)065535有符號整型signed int2字節(jié)-3276832767無符號長整型unsigned long4字節(jié)04294967295有符號長整型signed long4字節(jié)-21474836482147483647浮點(diǎn)型float4字節(jié)1.1755E-383.40E+38特殊功能寄存器型sfrsfr161字節(jié)2字節(jié)0255065535位類型bit、sbit1位0或1數(shù)據(jù)類型轉(zhuǎn)換1)自動(dòng)轉(zhuǎn)換轉(zhuǎn)換規(guī)則是向高精度數(shù)據(jù)類型轉(zhuǎn)換、向有符

6、號數(shù)據(jù)類型轉(zhuǎn)換。如字符型變量與整型變量相加時(shí),則位變量先轉(zhuǎn)換字符型或整型數(shù)據(jù),然后相加。2)強(qiáng)制轉(zhuǎn)換像ANSI C一樣,通過強(qiáng)制類型轉(zhuǎn)換的方式進(jìn)行轉(zhuǎn)換。如:unsignedintb;floatc;b=(int)c; 1.2.2 C51數(shù)據(jù)的存儲(chǔ)MCS-51單片機(jī)只有bit和unsigned char兩種數(shù)據(jù)類型支持機(jī)器指令,而其它類型的數(shù)據(jù)都需要轉(zhuǎn)換成bit或unsigned char型進(jìn)行存儲(chǔ)。為了減少單片機(jī)的存儲(chǔ)空間和提高運(yùn)行速度,要盡可能地使用unsigned char型數(shù)據(jù)。 一、位變量的存儲(chǔ)bit和sbit型位變量,直接存于RAM的位尋址空間,包括低128位和特殊功能寄存器位。 二、

7、字符變量的存儲(chǔ)字符變量(char):無論是unsigned char數(shù)據(jù)還是signed char數(shù)據(jù),均為1個(gè)字節(jié),能夠被直接存儲(chǔ)在RAM中,可以存儲(chǔ)在00 x7f區(qū)域,也可以存儲(chǔ)在0 x800 xff區(qū)域,與變量的定義有關(guān)。unsigned char數(shù):可直接被MSC-51接受signed char數(shù)據(jù):用補(bǔ)碼表示。需要額外的操作來測試、處理符號位,使用的是兩種庫函數(shù),代碼量大,運(yùn)算速度降低。三、整型變量的存儲(chǔ)整型變量(int):不管是unsigned int數(shù)據(jù)還是signed int數(shù)據(jù),均為2個(gè)字節(jié),其存儲(chǔ)方法是高位字節(jié)保存在低地址(在前面),低位字節(jié)保存在高地址(在后面) 。例如,

8、整型變量的值為0 x1234,在內(nèi)存中的存放如右圖所示。signed int數(shù)據(jù)用補(bǔ)碼表示。地址低高:1234:四、長整型變量的存儲(chǔ)長整型變量(long)為4個(gè)字節(jié),其存儲(chǔ)方法與整型數(shù)據(jù)一樣,是最高位字節(jié)保存的地址最低(在最前面),最低位字節(jié)保存的地址最高(在最后面)。如長整型變量的值為0 x12345678,在內(nèi)存中的存放方法如右圖所示。不管是unsigned long數(shù)據(jù)還是signed long數(shù)據(jù)。地址低高:12345678:五、浮點(diǎn)型變量的存儲(chǔ)浮點(diǎn)型變量(fload)占4個(gè)字節(jié),用指數(shù)方式表示,其具體格式與編譯器有關(guān)。對于Keil C,采用的是IEEE-754標(biāo)準(zhǔn),具有24位精度,尾

9、數(shù)的最高位始終為1,因而不保存。具體分布為:1位符號位,8位階碼位,23位尾數(shù),如下圖所示。 字節(jié)地址0123浮點(diǎn)數(shù)內(nèi)容SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM符號和階碼尾數(shù)高位尾數(shù)低位符號位S:1表示負(fù)數(shù),0表示正數(shù)。階碼:用移碼表示。如,實(shí)際階碼-126用1表示,實(shí)際階碼0用127表示,即實(shí)際階碼數(shù)加上127得到階碼的表達(dá)數(shù)。階碼數(shù)值范圍:-126+128。例如浮點(diǎn)數(shù)-12.5符號位為1,12.5的二進(jìn)制數(shù)為1100.1=1.1001E+0011,階碼數(shù)值為3+127=130=10000010B,尾數(shù)為1001。因此,其十六進(jìn)制數(shù)為0 xC1480000,則存儲(chǔ)結(jié)構(gòu)

10、如右圖所示。 地址低高:C1480000:說明:教材中存儲(chǔ)結(jié)構(gòu)是錯(cuò)的。1.3 C51變量的定義及數(shù)據(jù)存儲(chǔ)區(qū)域主要內(nèi)容1.3.1 C51變量的定義1.3.2 C51變量的存儲(chǔ)類型1.3.3 C51變量的存儲(chǔ)區(qū)域1.3.4 C51變量定義舉例1.3.5 C51變量的存儲(chǔ)模式1.3.6 C51變量的絕對定位1.3.1 C51變量的定義C51變量定義的一般格式為:存儲(chǔ)類型數(shù)據(jù)類型 存儲(chǔ)區(qū)變量名1=初值 ,變量名2=初值 ,或存儲(chǔ)類型存儲(chǔ)區(qū) 數(shù)據(jù)類型 變量名1=初值 ,變量名2=初值 ,可見變量(非位變量)的定義由4部分組成,即在變量定義時(shí),指定變量4種屬性。數(shù)據(jù)類型:在前面的4.2中已經(jīng)敘述過,對于變

11、量名也無須多說,下面主要解釋“存儲(chǔ)類型”和“存儲(chǔ)區(qū)”等概念。 1.3.2 C51變量的存儲(chǔ)類型存儲(chǔ)類型這個(gè)屬性我們?nèi)匝赜肁NSI C的說法,盡量不改變原來的含義。按照ANSI C,C語言的變量有4種存儲(chǔ)類型:動(dòng)態(tài)存儲(chǔ)(auto)靜態(tài)存儲(chǔ)(static)全局存儲(chǔ)(extern)寄存器存儲(chǔ)(register) 一、動(dòng)態(tài)存儲(chǔ)動(dòng)態(tài)(存儲(chǔ))變量:用auto定義的為動(dòng)態(tài)變量,也叫自動(dòng)變量。作用范圍:在定義它的函數(shù)內(nèi)或復(fù)合語句內(nèi)部。當(dāng)定義它的函數(shù)或復(fù)合語句執(zhí)行時(shí),C51才為變量分配存儲(chǔ)空間,結(jié)束時(shí)所占用的存儲(chǔ)空間釋放。定義變量時(shí),auto可以省略,或者說如果省略了存儲(chǔ)類型項(xiàng),則認(rèn)為是動(dòng)態(tài)變量。動(dòng)態(tài)變量一般分

12、配使用寄存器或堆棧。 二、靜態(tài)存儲(chǔ)靜態(tài)(存儲(chǔ))變量:用static定義的為靜態(tài)變量。分為內(nèi)部靜態(tài)和外部靜態(tài)變量。內(nèi)部靜態(tài)變量:在函數(shù)體內(nèi)定義的為內(nèi)部靜態(tài)變量。在函數(shù)內(nèi)可以任意使用和修改,函數(shù)運(yùn)行結(jié)束后會(huì)一直存在,但在函數(shù)外不可見,即在函數(shù)體外得到保護(hù)。外部靜態(tài)變量:在函數(shù)體外部定義的為外部靜態(tài)變量。在定義的文件內(nèi)可以任意使用和修改,外部靜態(tài)變量會(huì)一直存在,但在文件外不可見,即在文件外得到保護(hù)。 三、外部存儲(chǔ)外部(存儲(chǔ))變量:用extern聲明的變量為外部變量,是在其它文件定義過的全局變量。用extern聲明后,便可以在所聲明的文件中使用。需要注意的是:在定義變量時(shí),即便是全局變量,也不能使用e

13、xtern定義。 四、寄存器存儲(chǔ)寄存器(存儲(chǔ))變量:用register定義的變量為寄存器變量。寄存器變量存放在CPU的寄存器中,這種變量處理速度快,但數(shù)目少。C51中的寄存器變量: C51的編譯器在編譯時(shí),能夠自動(dòng)識別程序中使用頻率高的變量,并將其安排為寄存器變量,用戶不用專門聲明。 1.3.3 C51變量的存儲(chǔ)區(qū)域變量的存儲(chǔ)區(qū)屬性是單片機(jī)擴(kuò)展的概念,非常重要,它涉及到7個(gè)新的關(guān)鍵字。MCS-51單片機(jī)有四個(gè)存儲(chǔ)空間,分成三類,它們是片內(nèi)數(shù)據(jù)存儲(chǔ)空間、片外數(shù)據(jù)存儲(chǔ)空間和程序存儲(chǔ)空間。 MCS-51單片機(jī)有更多的存儲(chǔ)區(qū)域:由于片內(nèi)數(shù)據(jù)存儲(chǔ)器和片外數(shù)據(jù)存儲(chǔ)器又分成不同的區(qū)域,所以單片機(jī)的變量有更多

14、的存儲(chǔ)區(qū)域。在定義變量時(shí),必須明確指出是存放在哪個(gè)區(qū)域。表1-2 C51存儲(chǔ)區(qū)與存儲(chǔ)空間的對應(yīng)關(guān)系關(guān)鍵字對應(yīng)的存儲(chǔ)空間及范圍codeROM空間,64KB全空間data片內(nèi)RAM,直接尋址,低128字節(jié)bdata片內(nèi)RAM,位尋址區(qū)0 x200 x2f,可字節(jié)訪問idata 片內(nèi)RAM,間接尋址,256字節(jié),與 Ri 對應(yīng)pdata片外RAM,分頁尋址的256字節(jié)(P2不變), P2改變可尋址64KB全空間,與MOVX Ri 對應(yīng)xdata片外RAM,64KB全空間bit片內(nèi)RAM位尋找區(qū),位地址0 x000 x7f,128位1.3.4 C51變量定義舉例1)定義存儲(chǔ)在data區(qū)域的動(dòng)態(tài)unsi

15、gned char變量:unsigned char data sec=0, min=0, hou=0;2)定義存儲(chǔ)在data區(qū)域的靜態(tài)unsigned char變量:static unsigned char data scan_code=0 xfe;3)定義存儲(chǔ)在data區(qū)域的靜態(tài)unsigned int變量:static unsigned int data dd;4)定義存儲(chǔ)在bdata區(qū)域的動(dòng)態(tài)unsigned char變量:unsigned char bdata operate, operate1;/定義指示操作的可位尋址的變量5)定義存儲(chǔ)在idata區(qū)域的動(dòng)態(tài)unsigned char

16、數(shù)組:unsigned char idata temp20; 6)定義在pdata區(qū)域的動(dòng)態(tài)有符號int數(shù)組:int pdata send_data30;/定義存放發(fā)送數(shù)據(jù)的數(shù)組 7)定義存儲(chǔ)在xdata區(qū)域的動(dòng)態(tài)unsigned int數(shù)組:unsigned int xdata receiv_buf50;/定義存放接受數(shù)據(jù)的數(shù)組8)定義存儲(chǔ)在code區(qū)域的unsigned char數(shù)組:unsigned char code dis_code10=0 x3f, 0 x06, 0 x5b, 0 x4f, 0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /定義共陰極數(shù)碼管

17、段碼數(shù)組1.3.5 C51變量的存儲(chǔ)模式存儲(chǔ)模式:如果在定義變量時(shí)缺省了存儲(chǔ)區(qū)屬性,則編譯器會(huì)自動(dòng)選擇默認(rèn)的存儲(chǔ)區(qū)域,也就是存儲(chǔ)模式。變量的存儲(chǔ)模式也就是程序(或函數(shù))的編譯模式。編譯模式分為三種:小模式(small)、緊湊模式(compact)和大模式(large)。編譯模式由編譯控制命令決定。存儲(chǔ)模式(編譯模式)決定了變量的默認(rèn)存儲(chǔ)區(qū)域和參數(shù)的傳遞方法。 一、small模式在small模式下,變量的默認(rèn)存儲(chǔ)區(qū)域是“data”、“idata”,即未指出存儲(chǔ)區(qū)域的變量保存到片內(nèi)數(shù)據(jù)存儲(chǔ)器中,并且堆棧也安排在該區(qū)域中。small模式的特點(diǎn):存儲(chǔ)容量小,但速度快。在small模式下參數(shù)的傳遞:通過

18、寄存器、堆?;蚱瑑?nèi)數(shù)據(jù)存儲(chǔ)區(qū)完成的。 二、compact模式在compact模式下,變量的默認(rèn)存儲(chǔ)區(qū)域是“pdata”,即未指出存儲(chǔ)區(qū)域的變量保存到片外數(shù)據(jù)存儲(chǔ)器的一頁中,最大變量數(shù)為256字節(jié),并且堆棧也安排在該區(qū)域中。compact模式的其特點(diǎn):是存儲(chǔ)容量較small模式大,速度較small模式稍慢,但比large模式要快。在compact模式下參數(shù)的傳遞:通過片外數(shù)據(jù)區(qū)的一個(gè)固定頁完成的。 三、large模式在large模式下,變量的默認(rèn)存儲(chǔ)區(qū)域是“xdata”,即未指出存儲(chǔ)區(qū)域的變量保存到片外數(shù)據(jù)存儲(chǔ)器,最大變量數(shù)可達(dá)64KB,并且堆棧也安排在該區(qū)域中。large模式的特點(diǎn):存儲(chǔ)容量大

19、,速度慢large模式下參數(shù)的傳遞方式:參數(shù)的傳遞也是通過片外數(shù)據(jù)存儲(chǔ)器完成的。 C51支持混合模式:即可以對函數(shù)設(shè)置編譯模式,所以在large模式下,可以對某些函數(shù)設(shè)置為compact模式或small模式,從而提高運(yùn)行速度。默認(rèn)編譯模式:如果文件或函數(shù)未指明編譯模式,則編譯器按small模式處理。編譯模式控制命令: “#pragma small(或compact、large)”應(yīng)放在文件的開始。 1.3.6 C51變量的絕對定位C51有三種方式可以對變量(I/O端口)絕對定位:絕對定位關(guān)鍵字_at_ 、指針、庫函數(shù)的絕對定位宏。對于后兩種方式,在后面指針一節(jié)介紹。C51擴(kuò)展的關(guān)鍵字_at_專

20、門用于對變量作絕對定位,_at_使用在變量的定義中,其格式為:存儲(chǔ)類型 數(shù)據(jù)類型 存儲(chǔ)區(qū) 變量名1 _at_ 地址常數(shù),變量名2 舉例說明_at_的使用方法1)對data區(qū)域中的 unsigned char變量aa作絕對定位:unsignedchardata aa _at_ 0 x30;2)對pdata區(qū)域中的 unsigned int數(shù)組cc作絕對定位:unsignedint pdata cc10 _at_ 0 x34;3)對xdata區(qū)域中的 unsigned char變量printer_port作絕對定位:unsignedcharxdata printer_port _at_ 0 x7f

21、ff; 對變量絕對定位的幾點(diǎn)說明:1)絕對地址變量在定義時(shí)不能初始化,因此不能對code型變量絕對定位;2)絕對地址變量只能夠是全局變量,不能在函數(shù)中對變量絕對定位;3)絕對地址變量多用于I/O端口,一般情況下不對變量作絕對定位;3)位變量不能使用_at_絕對定位。1.4 C51位變量的定義主要內(nèi)容1.4.1 bit型位變量的定義1.4.2 sbit型位變量的定義1.4.1 bit型位變量的定義常說的位變量指的就是bit型位變量。C51的bit型位變量定義的一般格式為:存儲(chǔ)類型 bit 位變量名1=初值 ,位變量名2=初值 ,bit位變量被保存在RAM中的位尋址區(qū)域(字節(jié)地址為0 x200 x

22、2f,16字節(jié))。例如:bitflag_run,receiv_bit=0;static bitsend_bit; 兩點(diǎn)說明:1)bit型位變量與其它變量一樣,可以作為函數(shù)的形參,也可以作為函數(shù)的返回值,即函數(shù)的類型可以是位型的;2)位變量不能定義指針,不能定義數(shù)組。 1.4.2 sbit型位變量的定義對于能夠按位尋址的特殊功能寄存器、定義在位尋址區(qū)域的變量(字節(jié)型、整型、長整型),可以對其各位用sbit定義位變量。為了方便起見,分開討論按位尋址的特殊功能寄存器中位變量的定義、按位尋址的變量中位變量的定義。一、特殊功能寄存器中位變量定義能夠按位尋址的特殊功能寄存器中位變量定義的一般格式為:sbi

23、t位變量名 位地址表達(dá)式這里的位地址表達(dá)式有三種形式:直接位地址特殊功能寄存器名帶位號字節(jié)地址帶位號1、用直接位地址定義位變量這種情況下位變量的定義格式為:sbit位變量名 位地址常數(shù)這里的位地址常數(shù)范圍為0 x800 xff,實(shí)際是定義特殊功能寄存器的位。例如:sbitP0_0=0 x80; sbitP1_1=0 x91;sbitRS0=0 xd3; /定義PSW的第3位sbitET0=0 xa9; /定義IE的第1位 2、特殊功能寄存器名帶位號定義這時(shí)位變量的定義格式為:sbit位變量名 特殊功能寄存器名位號常數(shù)這里的位號常數(shù)為07。例如:sbitP0_3=P03; sbitP1_4=P1

24、4;sbitOV=PSW2; /定義PSW的第2位sbitES=IE4; /定義IE的第4位 3、寄存器地址帶位號定義位變量在這種情況下位變量的定義格式為:sbit位變量名 特殊功能寄存器地址位號常數(shù)這里的位號常數(shù)同上,為07。例如:sbitP0_6=0 x806; sbitP1_7=0 x907;sbitAC=0 xd06; /定義PSW的第6位sbitEA=0 xa87;/定義IE的第7位 4、幾點(diǎn)說明1)用sbit定義的位變量,必須能夠按位操作,而不能夠?qū)o位操作功能的位定義位變量。2)用sbit定義位變量,必須放在函數(shù)外面作為全局位變量,而不能在函數(shù)內(nèi)部定義。3)用sbit每次只能定義

25、一個(gè)位變量。4)對其它模塊定義的位變量(bit型或 sbit型)的引用聲明,都使用bit。5)用sbit定義的是一種絕對定位的位變量(因?yàn)槊质桥c確定位地址對應(yīng)的),具有特定的意義,在應(yīng)用時(shí)不能像bit型位變量那樣隨便使用。二、位尋址區(qū)變量的位定義對bdata型變量(字節(jié)型、整型、長整型) ,被保存在RAM中的位尋址區(qū),因此可以對bdata型變量各位作位變量定義。這樣,既可以對bdata型變量作字節(jié)(或整型、長整型)操作,也可以作位操作。bdata型變量的位定義格式:sbit 位變量名 bdata型變量名位號常數(shù) bdata型變量為在此之前應(yīng)該是定義過的,位號常數(shù)可以是07(8位字節(jié)變量),或

26、015(16位整型變量),或031(32位字長整型變量)。例如:unsignedchar bdataoperate;對operate的低4位作位變量定義:sbit flag_key=operate0; /鍵盤標(biāo)志位sbit flag_dis=operate1; /顯示標(biāo)志位sbit flag_mus=operate2; /音樂標(biāo)志位sbit flag_run=operate3; /運(yùn)行標(biāo)志位 1.5 C51特殊功能寄存器的定義主要內(nèi)容1.5.1 8位特殊功能寄存器的定義1.5.2 16位特殊功能寄存器的定義1.5.1 8位特殊功能寄存器的定義定義的一般格式為:sfr特殊功能寄存器名 地址常數(shù)地

27、址常數(shù)范圍:0 x800 xff。特殊功能寄存器定義例子(見reg51.h、reg52.h等文件):sfrP0=0 x80;/定義P0寄存器sfrP1=0 x90;/定義P1口寄存器sfrPSW=0 xd0;/定義PSWsfrIE=0 xa8;/定義IE 1.5.2 16位特殊功能寄存器的定義定義的一般格式為:sfr16 特殊功能寄存器名 地址常數(shù)地址常數(shù)范圍:0 x800 xff。例如(見reg51.h、reg52.h等文件):sfr16 DPTR=0 x82;sfr16 T2=0 xcc; /含TL2和TH2sfr16 RCAP2=0 xca; /含RCAP2L/和RCAP2H, 0 xc

28、a為RCAP2L的地址幾點(diǎn)說明:1)定義特殊功能寄存器中的地址必須在0 x800 xff范圍內(nèi)。2)定義特殊功能寄存器,必須放在函數(shù)外面作為全局變量。3)用sfr或sfr16每次只能定義一個(gè)特殊功能寄存器。4)像sbit一樣,用sfr或sfr16定義的是絕對定位的變量(因?yàn)槊质桥c確定地址對應(yīng)的),具有特定的意義,在應(yīng)用時(shí)不能像一般變量那樣隨便使用。 1.6 C51指針的定義主要內(nèi)容1.6.1 通用指針1.6.2 存儲(chǔ)器專用指針1.6.3 指針變換1.6.4 C51指針應(yīng)用1.6 C51指針的定義由于MCS-51單片機(jī)有三種不同類型的存儲(chǔ)空間,并且還有不同的存儲(chǔ)區(qū)域,因此C51指針的內(nèi)容更豐富

29、。指針除了具有像變量的四種屬性(存儲(chǔ)類型、數(shù)據(jù)類型、存儲(chǔ)區(qū)、變量名)外,按存儲(chǔ)區(qū),將指針分為通用指針和不同存儲(chǔ)區(qū)域的專用指針。 1.6.1 通用指針?biāo)^通用指針,就是通過該類指針可以訪問所有的存儲(chǔ)空間。在C51庫函數(shù)中通常使用這種指針來訪問。通用指針用3個(gè)字節(jié)來表示:第一個(gè)字節(jié):表示指針?biāo)赶虻拇鎯?chǔ)空間第二個(gè)字節(jié):為指針地址的高字節(jié)第三個(gè)字節(jié):為指針地址的低字節(jié)通用指針的定義與一般C語言指針的定義相同,其格式為:存儲(chǔ)類型 數(shù)據(jù)類型 *指針名1,*指針名2 ,例如:unsigned char *cpt;int *dpt;long *lpt;static char *ccpt; 通用指針的特點(diǎn):定

30、義簡單訪問所有空間訪問速度慢 1.6.2 存儲(chǔ)器專用指針?biāo)^存儲(chǔ)器專用指針,就是通過該類指針,只能夠訪問規(guī)定的存儲(chǔ)空間區(qū)域。指針本身占用1個(gè)字節(jié)(data *,idata *,bdata *,pdata *)或2個(gè)字節(jié)(xdata *,code *)。存儲(chǔ)器專用指針的一般定義格式為:存儲(chǔ)類型 數(shù)據(jù)類型 指向存儲(chǔ)區(qū) *指針存儲(chǔ)區(qū) 指針名1 ,*指針存儲(chǔ)區(qū) 指針名2, 指向存儲(chǔ)區(qū):是指針變量所指向的數(shù)據(jù)存儲(chǔ)空間區(qū)域。不能夠缺省。指針存儲(chǔ)區(qū):是指針變量本身所存儲(chǔ)的空間區(qū)域。缺省時(shí)認(rèn)為指針存儲(chǔ)區(qū)在默認(rèn)的存儲(chǔ)區(qū)域,其默認(rèn)存儲(chǔ)區(qū)域決定于所設(shè)定的編譯模式。指向和指針存儲(chǔ)區(qū),兩者可以是同一個(gè)區(qū)域,但多數(shù)情況下

31、不會(huì)是同一個(gè)區(qū)域。 存儲(chǔ)器專用指針例子:unsigned char data *cpt1, *cpt2; signed int idata *dpt1, *dpt2;unsigned char pdata *ppt; signed long xdata *lpt1, *lpt2;unsigned char code *ccpt;上面所定義的指針雖然所指向的空間不同,但指針變量本身都存儲(chǔ)在默認(rèn)的存儲(chǔ)區(qū)域。 又如:1)unsigned char data *idata cpt1,*idata cpt2; 2)signed int idata *data dpt1, *data dpt2; 3)un

32、signed char pdata *xdata ppt; 4)signed long xdata *lpt1, *xdata lpt2; 5)unsigned char code *data ccpt; 綠色關(guān)鍵字為指針?biāo)赶虻拇鎯?chǔ)區(qū)藍(lán)色關(guān)鍵字為指針本身所存儲(chǔ)的區(qū)域注意:(1)要區(qū)分指針變量指向的空間區(qū)域和指針變量本身所存儲(chǔ)的區(qū)域;(2)定義時(shí),前者不能缺省,而后者可以缺??;(3)指針變量的長度:指向不同的區(qū)域,占用的字節(jié)數(shù)不同。說明:指針變量本身所存儲(chǔ)的區(qū)域,在定義指針時(shí)一般都省略了,指針變量本身保存在缺省存儲(chǔ)的區(qū)域中。定義時(shí),缺省指針存儲(chǔ)的區(qū)域,顯得簡單,并且對初學(xué)者更容易理解。 1.6

33、.3 指針變換一、通用指針格式 由前面的討論知,通用指針由3個(gè)字節(jié)組成,第一個(gè)字節(jié)為數(shù)據(jù)的存儲(chǔ)區(qū)域,后兩個(gè)字節(jié)為指針地址,第一個(gè)字節(jié)的存儲(chǔ)區(qū)域編碼如表4-6所示。 表1-6 通用指針存儲(chǔ)區(qū)域編碼存儲(chǔ)區(qū)idataxdatapdatadatacode編 碼12345一、指針轉(zhuǎn)換指針轉(zhuǎn)換有兩種途徑,一種是顯式的編程轉(zhuǎn)換,另一種是隱式的自動(dòng)轉(zhuǎn)換。指針的編程轉(zhuǎn)換:(1)通用指針的第一字節(jié),與專用指針的指向數(shù)據(jù)區(qū)屬性,二者相互轉(zhuǎn)換;(2)通用指針后兩個(gè)字節(jié)的地址,與專用指針值的轉(zhuǎn)換。指針的隱式自動(dòng)轉(zhuǎn)換:由編譯器在進(jìn)行編譯時(shí)自動(dòng)完成。 1.6.4 C51指針應(yīng)用指針在PC機(jī)上的C語言中應(yīng)用很廣泛。在單片機(jī)中

34、,由于不使用操作系統(tǒng),指針的應(yīng)用可以獨(dú)立于變量,獨(dú)立地指向所需要訪問的存儲(chǔ)空間位置。本節(jié)通過例子來學(xué)習(xí)和認(rèn)識C51指針的這種獨(dú)立應(yīng)用性。下面介紹兩種利用指針訪問存儲(chǔ)區(qū)的方法。也可以訪問函數(shù)。二、通過指針定義的宏訪問存儲(chǔ)器1、訪問存儲(chǔ)器宏的定義用指針定義的、訪問存儲(chǔ)器宏的格式: #define 宏名 (數(shù)據(jù)類型 volatile 存儲(chǔ)區(qū)*)0)格式中的數(shù)據(jù)類型主要為無符號的字符型數(shù)、整型;格式中的存儲(chǔ)區(qū)域主要使用data、idata、pdata、xdata和code類型,不使用bdata存儲(chǔ)區(qū)類型。 格式中的關(guān)鍵字“volatile”: “volatile”是單片機(jī)中定義的,其含義為:這種變量在

35、程序執(zhí)行中可被隱含地改變而編譯器無法檢測到,告知編譯器不要做優(yōu)化處理,使應(yīng)用者能夠得到正確的變量值。volatile的應(yīng)用:volatile常用于定義寄存器,特別是狀態(tài)寄存器,因?yàn)闋顟B(tài)寄存器的值不是程序員設(shè)置,而是單片機(jī)在運(yùn)行中CPU設(shè)置的。特別說明:“volatile”的含義與教材上表述不太一致,此處表述直觀更容易理解。2、庫函數(shù)中訪問存儲(chǔ)器宏的原型C51編譯器提供了兩組用指針定義的絕對存儲(chǔ)器訪問的宏,其原型如下。 1)按字節(jié)訪問存儲(chǔ)器的宏:#define CBYTE (unsigned char volatile code*)0)#define DBYTE (unsigned char v

36、olatile data*)0)#define PBYTE(unsigned char volatile pdata*)0)#define XBYTE (unsigned char volatile xdata*)0) 2)按整型雙字節(jié)訪問存儲(chǔ)器的宏:#define CWORD (unsigned int volatile code*)0) #define DWORD (unsigned int volatile data*)0)#define PWORD (unsigned int volatile pdata*)0)#define XWORD (unsigned int volatile

37、xdata*)0)無idata型,不能訪問片內(nèi)RAM高128字節(jié)區(qū)域(0 x800 xff),需要時(shí)可以自己定義。這些宏定義原型放在absacc.h文件中,使用時(shí)需要用預(yù)處理命令把該頭文件包含到文件中,形式為:#include 。 3、絕對訪問存儲(chǔ)器宏的應(yīng)用使用宏定義訪問存儲(chǔ)器的形式類似于數(shù)組。1)按字節(jié)訪問存儲(chǔ)器宏的形式宏名地址即數(shù)組中的下標(biāo)就是存儲(chǔ)器的地址,因此使用起來非常方便。例如:DBYTE0 x30=48;/給片內(nèi)RAM送數(shù)據(jù)XBYTE0 x0002=0 x36;/給片外RAM送數(shù)據(jù)dis_buf0=CBYTETABLE+5; /從CODE區(qū)讀取數(shù)據(jù)2)按整型數(shù)訪問存儲(chǔ)器宏的形式宏名

38、下標(biāo)由于整型數(shù)占兩個(gè)字節(jié),所以下標(biāo)與地址的關(guān)系為:地址=下標(biāo)2。由于數(shù)組中的下標(biāo)與存儲(chǔ)器的地址是倍數(shù)關(guān)系,使用時(shí)要注意。例如:DWORD0 x20=0 x1234; /給0 x40、0 x41送數(shù)XWORD0 x0002=0 x5678;/給4、5單元送數(shù)通過指針定義的宏訪問存儲(chǔ)器這種方法,特別適用于訪問I/O口。 一、通過專用指針直接訪問存儲(chǔ)器使用指針直接訪問存儲(chǔ)器對PC機(jī)是禁止的,但對于單片機(jī)來說使用時(shí)注意是可以的。使用指針直接訪問存儲(chǔ)器方法是先定義所需要的指針,給指針賦地址值,然后使用指針訪問存儲(chǔ)器。例如:unsigned char xdata *xcpt;xcpt=0 x2000;*x

39、cpt=123; /給0 x2000送數(shù)xcpt+;*xcpt=234; /給0 x2001送數(shù)例1-1 編寫程序,將單片機(jī)片外數(shù)據(jù)存儲(chǔ)器中地址從0 x1000開始20個(gè)字節(jié)數(shù)據(jù),傳送到片內(nèi)數(shù)據(jù)存儲(chǔ)器地址從0 x30開始的區(qū)域。程序段如下:unsigned char data i, *dcpt; unsigned char xdata*xcpt; dcpt=0 x30;/給指針賦地址xcpt=0 x1000; for(i=0;i20;i+)*(dcpt+i)=*(xcpt+i); dcpt和xcpt兩個(gè)指針變量存儲(chǔ)在什么地方?例4-2 在數(shù)字濾波中有一種叫做“中值濾波”技術(shù),就是對采集的數(shù)據(jù)按

40、照從大到小或者從小到大進(jìn)行排序,然后取中間位置的數(shù)作為采樣值。試編寫一函數(shù),對存放在片內(nèi)數(shù)據(jù)存儲(chǔ)器中,從0 x50開始的21個(gè)單元的采樣數(shù)據(jù),用冒泡法排序進(jìn)行中值濾波,并把得到的中值數(shù)據(jù)返回。中值濾波函數(shù)如下:unsigned char median_filter() unsigned char data *point,i,j,n,d; for(i=0;i20;i+)/外層循環(huán)20次point = 0 x50;/point指向0 x50處n=20i;/n為內(nèi)層循環(huán)次數(shù)for(j=0;jn;j+)/內(nèi)層循環(huán)if(*point*(point+1)/從大到小排d=*point; *point=*(p

41、oint+1);*(point+1)=d;point+;/指針指向下一個(gè)數(shù)point=0 x50+10;/指向位于中間的數(shù)return *point;/返回得到的中值 1.7 C51的輸入/輸出主要內(nèi)容1.7.1 基本輸入/輸出函數(shù)1.7.2 格式輸出函數(shù)printf1.7.3 格式輸入函數(shù)scanfC51的輸入和輸出函數(shù)的形式雖然與ANSI C的一樣,但實(shí)際意義和使用方法都大不一樣,因此,有必要專門介紹一下C51的輸入/輸出函數(shù)。 在C51的I/O函數(shù)庫中定義的I/O函數(shù),都是以_getkey和putchar函數(shù)為基礎(chǔ)。這些I/O函數(shù)包括:字符輸入/輸出函數(shù)getchar和putchar,字

42、符串輸入/輸出函數(shù)gets和puts,格式輸入/輸出函數(shù)printf和scanf等。C51的輸入/輸出函數(shù),都是通過單片機(jī)的串行接口實(shí)現(xiàn)的。在使用這些I/O函數(shù)之前,必須先對單片機(jī)的串行口、定時(shí)器/計(jì)數(shù)器T1進(jìn)行初始化。假設(shè)單片機(jī)的晶振為11.0592MHz,波特率為9600bps,則初始化程序段為:SCON=0 x52;/設(shè)置串口方式1收、發(fā)TMOD=0 x20;/設(shè)置T1以模式2工作TL1=0 xfd;/設(shè)置T1低8位初值TH1=0 xfd;/設(shè)置T1自動(dòng)重裝初值TR1=1;/開T1 1.7.1 基本輸入/輸出函數(shù)1、基本輸入函數(shù)getkeygetkey函數(shù)是基本的字符輸入函數(shù),原型為ch

43、ar _getkey(void)函數(shù)功能:從單片機(jī)串行口讀入一個(gè)字符,如果沒有字符輸入則等待,返回值為讀入的字符,不顯示??芍厝牒瘮?shù)。字符輸入函數(shù)getchar()功能:與getkey基本相同,唯一的區(qū)別:還要從串行口返回字符。2基本輸出函數(shù)putcharputchar函數(shù)是基本的字符輸出函數(shù),其原型為:char putchar(char)函數(shù)功能:是從單片機(jī)的串行口輸出一個(gè)字符,返回值為輸出的字符。putchar為可重入函數(shù)。 1.7.2 格式輸出函數(shù)printf函數(shù)功能:通過單片機(jī)的串行口輸出若干任意類型的數(shù)據(jù)。格式如下:printf(格式控制,輸出參數(shù)表)格式控制是用雙引號括起來的字符串

44、,也稱為轉(zhuǎn)換控制字符串,它包括三種信息:格式說明符普通字符轉(zhuǎn)義字符。1)格式說明符:由百分號“%”和格式字符組成,其作用是指明輸出數(shù)據(jù)的格式,如%d、%c、%s等,詳細(xì)情況見表4-3。2)普通字符:這些字符按原樣輸出,主要用來輸出一些提示信息。3)轉(zhuǎn)義字符:由“”和字母或字符組成,它的作用是輸出特定的控制符,如轉(zhuǎn)義字符n的含義是輸出換行,詳細(xì)情況見表4-4。 表1-3 printf函數(shù)的格式字符表1-4 常用的轉(zhuǎn)義字符格式字符數(shù)據(jù)類型輸 出 格 式轉(zhuǎn)義字符含 義ASCII碼dint有符號十進(jìn)制數(shù)0空字符0 x00uint無符號十進(jìn)制數(shù)n換行符0 x0aoint無符號八進(jìn)制數(shù)r回車符0 x0dx

45、, Xint無符號十六進(jìn)制數(shù)t水平制表0 x09ffloat十進(jìn)制浮點(diǎn)數(shù)b退格符0 x08e, Efloat科學(xué)計(jì)數(shù)法的十進(jìn)制浮點(diǎn)數(shù)f換頁符0 x0cg, Gfloat自動(dòng)選擇e或f格式單引號0 x27cchar單個(gè)字符”雙引號0 x22s指針帶結(jié)束符的字符串反斜杠0 x5c用printf函數(shù)輸出例子(假設(shè)y已定義過,也賦值過):printf(“x=%d”,36) ;/從串行口輸出x=36printf(“y=%d”,y) ;/從串行口輸出y=y的值printf(“c1=%c,c2=%c”,A,B) ; /從串行口輸出c1=A,c2=Bprintf(“%sn”,“OK,Send data beg

46、in!”) ;/從串行口輸出OK, Send data begin!和n 1.7.2 格式輸入函數(shù)scanfscanf函數(shù)的功能:通過單片機(jī)串行口實(shí)現(xiàn)各種數(shù)據(jù)輸入。函數(shù)格式如下:scanf(格式控制,地址列表)格式控制格式控制與printf函數(shù)的類似,也是用雙引號括起來的一些字符,包括三種信息:格式說明符、普通字符和空白字符。1)格式說明符:由百分號“%”和格式字符組成,其作用是指明輸入數(shù)據(jù)的格式,見表4-5。 2)普通字符:在輸入時(shí),要求這些字符按原樣輸入。3)空白字符:包括空格、制表符和換行符等,這些字符在輸入時(shí)被忽略。地址列表:是由若干個(gè)地址組成,它可以是指針變量、變量地址(取地址運(yùn)算符

47、“&”加變量)、數(shù)組地址(數(shù)組名)或字符串地址(字符串名)等。 用scanf函數(shù)輸入例子(假設(shè)x、y、z、c1、c2是定義過的變量,str1是定義過的指針):scanf(“%d”,&x);scanf(“%d%d”,&y,&z);scanf(“%c%c”,&c1,&c2);scanf(“%s”,str1);在實(shí)際的串行通信中,傳輸?shù)臄?shù)據(jù)多數(shù)是字符型和字符串,以字符串居多,往往把數(shù)字型數(shù)據(jù)轉(zhuǎn)換成字符串傳輸。 例1-3 有一單片機(jī)時(shí)鐘系統(tǒng),為了演示輸出函數(shù)putchar和輸入函數(shù)getkey的應(yīng)用,編寫程序,用串行口方式1自發(fā)自收,每一秒鐘從串行口發(fā)送一次時(shí)間數(shù)據(jù)的時(shí)、分、秒,從串行口接收到數(shù)據(jù)后,

48、送給6位數(shù)碼管顯示。設(shè)晶振頻率為11.0592MHz,波特率為9600bps。不用編寫時(shí)鐘計(jì)時(shí)函數(shù)和數(shù)碼管顯示函數(shù)。#include /包含頭文件#include /包含I/O函數(shù)庫unsigned char data t13;/存放原始的時(shí)分秒unsigned char data dis_buf6;/數(shù)碼管顯示void main(void) unsigned char data t23;/放接收的時(shí)間unsigned char data sec0=61;/秒備份unsigned char data i;SCON=0 x52;/串行口初始化TMOD=0 x20; /設(shè)置定時(shí)器工作模式TH1=0

49、 xfd; /設(shè)置T1重裝的初值TR1=1; /開T1運(yùn)行while(1) if(sec0!=t12)/判斷秒是否已經(jīng)改變 putchar(t1i);t2i+=_getkey(); if(i2) dis_buf0=t20/10; dis_buf1=t20%10; dis_buf2=t21/10; dis_buf3=t21%10; dis_buf4=t22/10; dis_buf5=t22%10; i=0; sec0=t12;/更新秒備份 display( ); /調(diào)用數(shù)碼管掃描顯示函數(shù)1.8 C51函數(shù)的定義主要內(nèi)容1.8.1 C51函數(shù)的定義1.8.2 C51中斷函數(shù)的定義 C51函數(shù)的定義

50、與ANSI C相似,但有更多的屬性要求。本節(jié)先討論函數(shù)的一般定義,然后專門給出中斷函數(shù)的定義,因?yàn)橹袛嗪瘮?shù)有其特殊性。 1.8.1 C51函數(shù)的定義在C51中,函數(shù)的定義與ANSI C中是相同的。唯一不同的就是在函數(shù)的后面需要帶上若干個(gè)C51的專用關(guān)鍵字。C51函數(shù)定義的一般格式如下:返回類型 函數(shù)名(形參表) 函數(shù)模式 reentrant interrupt m using n局部變量定義執(zhí)行語句 各屬性含義如下:函數(shù)模式:也就是編譯模式、存儲(chǔ)模式,可以為small、compact和large。缺省時(shí)則使用文件的編譯模式。reentrant:表示重入函數(shù)。所謂可重入函數(shù),就是允許被遞歸調(diào)用的

51、函數(shù)。是C51定義的關(guān)鍵字。 在編譯時(shí)會(huì)為重入函數(shù)生成一個(gè)堆棧,通過這個(gè)堆棧來完成參數(shù)的傳遞和存放局部變量。重入函數(shù)不能使用bit型參數(shù);函數(shù)返回值也不能是bit型。interrupt m:中斷關(guān)鍵字和中斷號。 interrupt是C51定義的。C51支持32個(gè)中斷源中斷入口地址與中斷號m的關(guān)系:中斷入口地址38m。表1-7 單片機(jī)中斷源與中斷號的關(guān)系中斷源外中斷0T0中斷外中斷1T1中斷串行中斷T2中斷中斷號012345中斷入口地址0 x00030 x000b0 x00130 x001b0 x00230 x002busing n:選擇工作寄存器組和組號,n可以為03,對應(yīng)第0組到第3組。關(guān)鍵

52、字using是C51定義的。如果函數(shù)有返回值,不能使用該屬性,因?yàn)榉祷刂凳谴嬗诩拇嫫髦?,函?shù)返回時(shí)要恢復(fù)原來的寄存器組,導(dǎo)致返回值錯(cuò)誤。 1.8.2 C51中斷函數(shù)的定義C51函數(shù)的定義實(shí)際上已經(jīng)包含了中斷服務(wù)函數(shù),但為了明確起見,下面專門給出中斷處理函數(shù)的具體定義形式:void 函數(shù)名(void) 函數(shù)模式 interrupt m using n局部變量定義執(zhí)行語句 中斷服務(wù)函數(shù)需要注意以下幾點(diǎn):1)中斷服務(wù)函數(shù)不傳遞參數(shù);2)中斷服務(wù)函數(shù)沒有返回值;3)中斷服務(wù)函數(shù)必須有interrupt m屬性;4)進(jìn)入中斷服務(wù)函數(shù),ACC、B、PSW會(huì)進(jìn)棧,根據(jù)需要,DPL、DPH也可能進(jìn)棧,如果沒有

53、using n屬性,R0R7也可能進(jìn)棧,否則不進(jìn)棧;5)在中斷服務(wù)函數(shù)中調(diào)用其它函數(shù),被調(diào)函數(shù)最好設(shè)置為可重入的,因?yàn)橹袛嗍请S機(jī)的,有可能中斷服務(wù)函數(shù)所調(diào)用的函數(shù)出現(xiàn)嵌套調(diào)用;6)不能夠直接調(diào)用中斷服務(wù)函數(shù)。 例1-4 編寫程序,使用定時(shí)器/計(jì)數(shù)器0定時(shí)并產(chǎn)生中斷,實(shí)現(xiàn)從P1.7產(chǎn)生方波的功能。程序如下:#include #defineTIMER0L0 x18/設(shè)振蕩頻率為12MHz#defineTIMER0H0 xfc/定時(shí)1ms(1000微秒)void timer0_int(void) interrupt 1TL0=TIMER0L;TH0=TIMER0H;P1_7=P1_7;/產(chǎn)生的方波頻

54、率為500Hz voidmain(void)TMOD=0 x01;/設(shè)置T1模式1定時(shí)TL0=TIMER0L;/設(shè)置T0低8位初值TH0=TIMER0H;/設(shè)置T0高8位初值IE=0 x82;/開T0中斷和總中斷TR0=1;/開T0運(yùn)行while(1);/等待中斷,產(chǎn)生方波 1.9 C51與匯編語言混合編程主要內(nèi)容1.9.1 在C51程序中嵌入?yún)R編程序1.9.2 C51程序與匯編程序混合編程混合編程有兩種方式:一種是在C語言函數(shù)中嵌入?yún)R編語言程序,程序中沒有獨(dú)立的匯編語言函數(shù),只有個(gè)別C語言函數(shù)中嵌入有匯編程序;另一種是C語言文件與匯編語言文件混合編程,程序中有獨(dú)立的匯編程序函數(shù)和匯編語言文件

55、。無論是哪種混合編程方式,采用C51后,程序的大部分是C語言,只有少部分是匯編語言。 1.9.1 在C51程序中嵌入?yún)R編程序其方法是用編譯控制指令“#pragma src”、“#pragma asm”和“#pragma endasm”實(shí)現(xiàn)?!?pragma src”是控制編譯器將C源文件編譯成匯編文件,“#pragma src”要放在文件的開始;“#pragma asm”和“#pragma endasm”指示匯編語言程序的開始和結(jié)束,分別放在匯編程序段的前面和后面。例1-5 編寫一從單片機(jī)P1口做循環(huán)右移輸出的流水燈子程序。#pragma src/指示將C文件編譯成匯編文件void round

56、_lamp(void)static unsigned char lamp=0 x55;P1=lamp; # pragma asm/指示匯編語言程序開始MOVA,lamp/對變量lamp做循環(huán)右移RRAMOVlamp,A# pragma endasm/指示匯編語言程序結(jié)束 1.9.2 C51程序與匯編程序混合編程在這種情況下,C語言與匯編語言程序都是獨(dú)立的文件,它們的函數(shù)要相互調(diào)用,這就涉及到了匯編語言程序的參數(shù)傳遞和函數(shù)命名兩個(gè)問題。下面先討論匯編語言函數(shù)的命名和參數(shù)傳遞問題,然后討論混合編程。 主要內(nèi)容一、C51函數(shù)的命名規(guī)則二、C51函數(shù)段與數(shù)據(jù)段的格式三、C51函數(shù)的參數(shù)傳遞規(guī)則四、匯編

57、語言文件及函數(shù)編寫方法五、匯編語言文件編程舉例六、在C語言中調(diào)用匯編語言的方法一、C51函數(shù)的命名規(guī)則從表4-8中可以看出,C51函數(shù)的命名規(guī)則主要有:函數(shù)名字符串 /不傳遞參數(shù)的函數(shù)_函數(shù)名字符串 /通過寄存器傳遞參數(shù)_?函數(shù)名字符串/通過堆棧傳遞參數(shù)的可重入函數(shù) C51函數(shù)名還有其它的格式,如通過存儲(chǔ)器傳遞參數(shù)的函數(shù)等,在混合編程中基本不用,所以不再介紹。 表1-8 C51中函數(shù)名的轉(zhuǎn)換規(guī)則C51函數(shù)聲明匯編函數(shù)名說 明 type func1(void)FUNC1調(diào)用時(shí)不傳遞參數(shù),但有返回值,函數(shù)名不變 type func2(args)_FUNC2通過寄存器傳遞參數(shù),函數(shù)名加前綴“_” t

58、ype func3(args) reentrant_?FUNC3重入函數(shù),通過堆棧傳遞參數(shù),函數(shù)名加前綴“_?”二、C51函數(shù)段與數(shù)據(jù)段的格式C51編譯后對每個(gè)函數(shù)都分配一個(gè)獨(dú)立的CODE段,并且匯編函數(shù)名字還要帶上模塊名,所以C51匯編語言函數(shù)段的格式為:?PR?函數(shù)名字符串?模塊名?PR?_函數(shù)名字符串?模塊名?PR?_?函數(shù)名字符串?模塊名如果函數(shù)中定義有局部變量,編譯時(shí)也給局部變量分配數(shù)據(jù)段,數(shù)據(jù)段的格式為:?數(shù)據(jù)段前綴?函數(shù)名?數(shù)據(jù)類型表1-9 C51段類型前綴與存儲(chǔ)段前綴存儲(chǔ)區(qū)類型說 明?PR?code可執(zhí)行程序段?CO?code程序存儲(chǔ)器中的常數(shù)數(shù)據(jù)段?BI?bit內(nèi)部RAM的位

59、類型數(shù)據(jù)段?BA?bdata內(nèi)部RAM的可位尋址的數(shù)據(jù)段?DT?data內(nèi)部RAM的數(shù)據(jù)段?ID?idata內(nèi)部RAM的間接尋址的數(shù)據(jù)段?PD?pdata外部RAM的分頁數(shù)據(jù)段?XD?xdata外部RAM的一般數(shù)據(jù)段三、C51函數(shù)的參數(shù)傳遞規(guī)則分為調(diào)用時(shí)的參數(shù)傳遞和返回時(shí)參數(shù)的傳遞。1、調(diào)用時(shí)參數(shù)的傳遞分三種情況:少于等于3個(gè)參數(shù)時(shí)通過寄存器傳遞(寄存器不夠用時(shí)通過存儲(chǔ)區(qū)傳遞);多于3個(gè)時(shí)有一部分通過存儲(chǔ)區(qū)傳遞;對于重入函數(shù)參數(shù)通過堆棧傳遞。通過寄存器傳遞速度最快。表4-10給出了第一種情況通過寄存器傳遞參數(shù)的規(guī)則。 表1-10 C51利用寄存器傳遞參數(shù)規(guī)則參數(shù)號charintlong,flo

60、at一般指針1R7R6,R7(低字節(jié))R4R7R1R2R3(R3為存儲(chǔ)區(qū),R2為高地址, R1為低地址)2R5R4,R5(低字節(jié))R4R7或存儲(chǔ)區(qū)R1R2R3或存儲(chǔ)區(qū)3R3R2,R3(低字節(jié))存儲(chǔ)區(qū)R1R2R3或存儲(chǔ)區(qū)2、函數(shù)返回值的傳遞當(dāng)函數(shù)有返回值時(shí),通過寄存器傳遞。表1-11 C51函數(shù)返回值傳遞規(guī)則返回類型使用的寄存器說 明bitC(進(jìn)位標(biāo)志)由進(jìn)位標(biāo)志位返回char或1字節(jié)指針R7由R7返回int或2字節(jié)指針R6,R7高字節(jié)在R6,低字節(jié)在R7longR4R7高字節(jié)在R4,低字節(jié)在R7floatR4R732位IEEE格式一般指針R1R3R3為存儲(chǔ)區(qū),R1為低地址四、匯編語言文件及函數(shù)

溫馨提示

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

評論

0/150

提交評論