單片機(jī)C語言應(yīng)用程序設(shè)計(jì)_第1頁
單片機(jī)C語言應(yīng)用程序設(shè)計(jì)_第2頁
單片機(jī)C語言應(yīng)用程序設(shè)計(jì)_第3頁
單片機(jī)C語言應(yīng)用程序設(shè)計(jì)_第4頁
單片機(jī)C語言應(yīng)用程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 一一 C51基礎(chǔ)知識基礎(chǔ)知識1.1 C語言與語言與MCS-511.2 C51數(shù)據(jù)類型及在數(shù)據(jù)類型及在MCS-51中的存儲方式中的存儲方式1.3 C51數(shù)據(jù)的存儲類型與數(shù)據(jù)的存儲類型與MCS-51存儲結(jié)構(gòu)存儲結(jié)構(gòu)1.4 MCS-51特殊功能寄存器特殊功能寄存器(SFR)的的C51定義定義1.5 MCS-51并行接口的并行接口的C51定義定義1.6 位變量的位變量的C51定義定義1.7 C51構(gòu)造數(shù)據(jù)類型構(gòu)造數(shù)據(jù)類型1.8 模塊化程序開發(fā)過程模塊化程序開發(fā)過程單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.1 C語言與語言與MCS51 用匯編程序設(shè)計(jì)MCS51系列單片機(jī)應(yīng)用程序時,必須要考

2、慮其存儲器結(jié)構(gòu),尤其必須考慮其片內(nèi)數(shù)據(jù)存儲器與特殊功能寄存器正確、合理的使用以及按實(shí)際地址處理端口數(shù)據(jù)。用C語言編寫MCS51單片機(jī)的應(yīng)用程序,雖然不像用匯編語言那樣具體地組織、分配存儲器資源和處理端口數(shù)據(jù),但在C語言編程中,對數(shù)據(jù)類型與變量的定義,必須要與單片機(jī)的存儲結(jié)構(gòu)相關(guān)聯(lián),否則編譯器不能正確地映射定位。用C語言編寫單片機(jī)應(yīng)用程序與編寫標(biāo)準(zhǔn)的C語言程序的不同之處就在于根據(jù)單片機(jī)存儲結(jié)構(gòu)及內(nèi)部資源定義相應(yīng)的C語言中的數(shù)據(jù)類型和變量,其它的語法規(guī)定、程序結(jié)構(gòu)及程序設(shè)計(jì)方法都與標(biāo)準(zhǔn)的C語言程序設(shè)計(jì)相同。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 用C語言編寫的應(yīng)用程序必須經(jīng)單片機(jī)的C語言編譯器(簡稱C51),

3、轉(zhuǎn)換生成單片機(jī)可執(zhí)行的代碼程序。支持MCS51系列單片機(jī)的C語言編譯器有很多種。如American Automation、Auocet、BSO/TASKING、DUNFIELD SHAREWARE、KEIL/Franklin等。其中KEIL/Franklin以它的代碼緊湊和使用方便等特點(diǎn)優(yōu)于其它編譯器。本章是針對這種編譯器介紹 MCS51單片機(jī)C語言程序設(shè)計(jì)。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.2 C51數(shù)據(jù)類型及在數(shù)據(jù)類型及在MCS-51中的存儲方式中的存儲方式1.2.1 C51的數(shù)據(jù)類型的數(shù)據(jù)類型 Franklin C51編譯器具體支持的數(shù)據(jù)類型有:位型(bit)、無符號字符(unsigned

4、 char)、有符號字符(singed char)、無符號整型(unsigned int )、有符號整型(signed int )、無符號長整型(unsigned long )、有符號長整型(signed long )、浮點(diǎn)型(float)和指針類型等。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 表表7.1 Franklin C51的數(shù)據(jù)類型的數(shù)據(jù)類型數(shù)據(jù)類型長度(bit)長度(byte)值域bit110,1unsigned char810255signed char81128127unsigned int 162065535signed int 1623276832767unsigned long324042

5、94967295signed long 32421474836482147483647float 3241.176E383.40E+38(6位數(shù)字)double6481.176E383.40E+38(10位數(shù)字)一般指針243存儲空間065535單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.2.2 C51數(shù)據(jù)在數(shù)據(jù)在MCS-51中的存儲方式中的存儲方式 位變量(bit):與MCS-51硬件特性操作有關(guān)的可以定義成位變量。位變量必須定位在MCS-51單片機(jī)片內(nèi)RAM的位尋址空間中。 字符變量(char):字符變量的長度為1 byte即8位。這很合適MCS-51單片機(jī),因?yàn)镸CS-51單片機(jī)每次可處理8位數(shù)據(jù)。對

6、于無符號變量(unsigned char)的值域范圍是0255。對于有符號字符變量(signed char),最具有重要意義的位是最高位上的符號標(biāo)志位(msb)。此位為1代表負(fù),為0代表正。有符號字符變量和無符號字符變量在表示0127的數(shù)值時,其含義是一樣的,都是00 x7F。負(fù)數(shù)一般用補(bǔ)碼表示,即用11111111表示-1, 用11111110表示-2。當(dāng)進(jìn)行乘除法運(yùn)算時,符號問題就變得十分復(fù)雜,而C51編譯器會自動地將相應(yīng)的庫函數(shù)調(diào)入程序中來解決這個問題。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 整型變量(int): 整型變量的長度為16位。與8080和8086 CPU系列不同,MCS-51系列單片機(jī)將i

7、nt型變量的高位字節(jié)數(shù)存放在低地址字節(jié)中,低位字節(jié)數(shù)存放在高地址字節(jié)中。有符號整型變量(signed int)也使用msb位作符號標(biāo)志位,并使用二進(jìn)制補(bǔ)碼表示數(shù)值??芍苯邮褂脦追N專用的機(jī)器指令來完成多字節(jié)的加、減、乘、除運(yùn)算。整型變量值0 x1234以圖7.1所示的方式存放在內(nèi)存中。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 圖1.1 整型數(shù)的存儲結(jié)構(gòu) 0 x120 x34+0+1地址 0 x120 x340 x560 x78.+0+1+2+3地址 圖1.2 長整型變量的存儲結(jié)構(gòu) 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 浮點(diǎn)型變量(float): 浮點(diǎn)型變量為32位,占4個字節(jié),許多復(fù)雜的數(shù)學(xué)表達(dá)式都采用浮點(diǎn)變量數(shù)據(jù)類型。應(yīng)

8、用符號位表示數(shù)的符號,用階碼和尾數(shù)表示數(shù)的大小。 用它們進(jìn)行任何數(shù)學(xué)運(yùn)算都需要使用由編譯器決定的各種不同效率等級的庫函數(shù)。Franklin C51的浮點(diǎn)變量數(shù)據(jù)類型的使用格式與IEEE-754標(biāo)準(zhǔn)有關(guān),具有24位精度,尾數(shù)的高位始終為1,因而不保存,位的分布如下: 1位符號位。 8位指數(shù)位。 23位尾數(shù)。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 符號位是最高位,尾數(shù)為低23位,內(nèi)存中按字節(jié)存儲順序如下:地址地址+0+1+2+3內(nèi)容內(nèi)容MMMMMMMMMMMMMMMMEMMMMMMMSEEEEEEE 其中,S為符號位,1表示負(fù),0表示正;E為階碼;M為23位尾數(shù),最高位為1。 浮點(diǎn)變量值 -12.5的十進(jìn)制為

9、:0 xC1480000,它按圖7.3所示方式存于內(nèi)存中。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 0 x000 x000 x480 xC1.+0+1+2+3地址 圖1.3 浮點(diǎn)數(shù)的存儲結(jié)構(gòu) 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 在編程時,如果只強(qiáng)調(diào)運(yùn)算速度而不進(jìn)行負(fù)數(shù)運(yùn)算時,最好采用無符號(unsigned)格式。 無符號字符類型的使用:無論何時,應(yīng)盡可能使用無符號字符變量,因?yàn)樗苤苯颖籑CS-51所接受?;谕瑯拥脑颍矐?yīng)盡量使用位變量。有符號字符變量雖然也只占用一個字節(jié),但需要進(jìn)行額外的操作來進(jìn)行測試代碼的符號位。這無疑會降低代碼效率。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 使用簡化形式定義數(shù)據(jù)類型。其方法是在源程序開頭使用

10、#define語句自定義簡化的類型標(biāo)識符。例如:#define uchar unsigned char #define uint unsigned int 這樣,在編程中,就可以用uchar代替unsigned char,用uint代替unsigned int來定義變量。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.3 C51數(shù)據(jù)的存儲類型與數(shù)據(jù)的存儲類型與MCS-51存儲結(jié)構(gòu)存儲結(jié)構(gòu)表表 1.2 C51存儲類型與存儲類型與MCS-51存儲空間的對應(yīng)關(guān)系存儲空間的對應(yīng)關(guān)系存儲類型與存儲空間的對應(yīng)關(guān)系 data 直接尋址片內(nèi)數(shù)據(jù)存儲區(qū),訪問速度快(128字節(jié)) bdata 可位尋址片內(nèi)數(shù)據(jù)存儲區(qū),允許位與字節(jié)混

11、合訪問(16字節(jié)) idata 間接尋址片內(nèi)數(shù)據(jù)存儲區(qū),可訪問片內(nèi)全部RAM地址空間(256字節(jié)) pdata 分頁尋址片外數(shù)據(jù)存儲區(qū)(256字節(jié))由MOV Ri訪問(i=0,1) xdata 片外數(shù)據(jù)存儲區(qū)(64 KB)由MOVX DPTR訪問 code 程序存儲器64 KB空間,由MOVC DPTR訪問單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 表表1.3 C51存儲類型及其數(shù)據(jù)長度和值域存儲類型及其數(shù)據(jù)長度和值域存儲類型長度(bit)長度(byte)值域范圍data810255idata810255pdata810255xdata162065 535code162065 535單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 帶

12、存儲類型的變量的定義的一般格式為 數(shù)據(jù)類型 存儲類型 變量名帶存儲類型的變量定義舉例:char data var1;bit bdata flags;float idata x,y,z;unsigned int pdata var2;unsigned char vector34;單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 表表 1.4 存儲模式說明存儲模式說明存儲模式說 明SMALL默認(rèn)的存儲類型是data,參數(shù)及局部變量放入可直接尋址片內(nèi)RAM的用戶區(qū)中(最大128字節(jié))。另外所有對象(包括堆棧),都必須嵌入片內(nèi)RAM。棧長很關(guān)鍵,因?yàn)閷?shí)際棧長依賴于函數(shù)嵌套調(diào)用層數(shù)COMPACT默認(rèn)的存儲類型是pdata,參數(shù)

13、及局部變量放入分頁的外部數(shù)據(jù)存儲區(qū),通過R0或R1間接訪問,棧空間位于片內(nèi)數(shù)據(jù)存儲區(qū)中LARGE默認(rèn)的存儲類型是xdata,參數(shù)及局部變量直接放入片外數(shù)據(jù)存儲區(qū),使用數(shù)據(jù)指針DPTR來進(jìn)行尋址。用此數(shù)據(jù)指針進(jìn)行訪問效率較低,尤其對兩個或多個字節(jié)的變量,這種數(shù)據(jù)類型的訪問機(jī)制直接影響代碼的長度單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.4 MCS-51特殊功能寄存器特殊功能寄存器(SFR)的的C51定義定義 MCS-51單片機(jī)中,除了程序計(jì)數(shù)器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器(SFR),分散在片內(nèi)RAM區(qū)的高128字節(jié)中,地址范圍為80H0FFH。SFR中有11個寄存器具有位尋址能

14、力,它們的字節(jié)地址都能被8整除,即字節(jié)地址是以8或0為尾數(shù)的。 為了能直接訪問這些SFR,F(xiàn)ranklin C51提供了一種自主形式的定義方法,這種定義方法與標(biāo)準(zhǔn)C語言不兼容,只適用于對MCS-51系列單片機(jī)進(jìn)行C語言編程。特殊功能寄存器C51定義的一般語法格式如下:sfr sfr-name = int constant;單片機(jī)C語言應(yīng)用程序設(shè)計(jì) sfr是定義語句的關(guān)鍵字,其后必須跟一個MSC-51單片機(jī)真實(shí)存在的特殊功能寄存器名,=后面必須是一個整型常數(shù),不允許帶有運(yùn)算符的表達(dá)式,是特殊功能寄存器sfr-name的字節(jié)地址,這個常數(shù)值的范圍必須在SFR地址范圍內(nèi),位于0 x800 xFF。例

15、如:sfr SCON=0 x98; /* 串口控制寄存器地址98H */sfr TMOD=0 x89;/* 定時器/計(jì)數(shù)器方式控制寄存器地址89H */單片機(jī)C語言應(yīng)用程序設(shè)計(jì) MCS-51系列單片機(jī)的特殊功能寄存器的數(shù)量與類型不盡相同,因此建議將所有特殊的sfr定義放入一個頭文件中,該文件應(yīng)包括MCS-51單片機(jī)系列機(jī)型中的SFR定義。C51編譯器的reg51.h頭文件就是這樣一個文件。 在新的MCS-51系列產(chǎn)品中,SFR在功能上經(jīng)常組合為16位值,當(dāng)SFR的高字節(jié)地址直接位于低字節(jié)之后時,對16位SFR的值可以直接進(jìn)行訪問。例如52子系列的定時器/計(jì)數(shù)器2就是這種情況。為了有效地訪問這類

16、SFR,可使用關(guān)鍵字sfr16來定義,其定義語句的語法格式與8位SFR相同,只是=后面的地址必須用16位SFR的低字節(jié)地址,即低字節(jié)地址作為sfr16的定義地址。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 例如: sfr16 T2 = 0 xCC /*定時器/計(jì)數(shù)器2:T2低8位地址為0CCH,T2高8位地址為0CDH*/ 這種定義適用于所有新的16位SFR,但不能用于定時器/計(jì)數(shù)器0和1。 對于位尋址的SFR中的位,C51的擴(kuò)充功能支持特殊位的定義,像SFR一樣不與標(biāo)準(zhǔn)C兼容,使用sbit來定義位尋址單元。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 第一種格式: sbit bit-name = sfr-nameint cons

17、tant; sbit是定義語句的關(guān)鍵字,后跟一個尋址位符號名(該位符號名必須是MCS-51單片機(jī)中規(guī)定的位名稱),=后的sfr-name必須是已定義過的SFR的名字,后的整常數(shù)是尋址位在特殊功能寄存器sfr-name中的位號,必須是07范圍中的數(shù)。例如: sfr PSW=0 xD0 ; /* 定義PSW寄存器地址為D0H */ sbit OV=PSW2 ; /* 定義OV位為PSW.2,地址為D2H */ sbit CY=PSW7 ; /* 定義CY位為PSW.7,地址為D7H */單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 第二種格式:sbit bit-name = int constantint const

18、ant; =后的int constant為尋址地址位所在的特殊功能寄存器的字節(jié)地址,符號后的int constant為尋址位在特殊功能寄存器中的位號。例如: sbit OV=0XD02 ;/* 定義OV位地址是D0H字節(jié)中的第2位 */ sbit CY=0XD07 ;/* 定義CY位地址是D0H字節(jié)中的第7位 */單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 第三種格式:sbit bit-name = int constant; =后的int constant為尋址位的絕對位地址。例如: sbit OV=0XD2 ;/* 定義OV位地址為D2H */ sbit CY=0XD7 ;/* 定義CY位地址為D7H */

19、 特殊功能位代表了一個獨(dú)立的定義類,不能與其它位定義和位域互換。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.5 MCS-51并行接口的并行接口的C51定義定義 MCS-51系列單片機(jī)并行I/O接口除了芯片上的4個I/O口(P0 P3)外,還可以在片外擴(kuò)展I/O口。MCS-51單片機(jī)I/O口與數(shù)據(jù)存儲器統(tǒng)一編址,即把一個I/O口當(dāng)作數(shù)據(jù)存儲器中的一個單元來看待。 使用C51進(jìn)行編程時,MCS-51片內(nèi)的I/O口與片外擴(kuò)展的I/O可以統(tǒng)一在一個頭文件中定義,也可以在程序中(一般在開始的位置)進(jìn)行定義,其定義方法如下: 對于MCS-51片內(nèi)I/O口按特殊功能寄存器方法定義。例如:sfr P0=0 x80 ; /*

20、 定義P0口,地址為80H */sfr P1=0 x90 ; /* 定義P1口,地址為90H */單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 對于片外擴(kuò)展I/O口,則根據(jù)硬件譯碼地址,將其視作為片外數(shù)據(jù)存儲器的一個單元,使用#define語句進(jìn)行定義。例如#include #define PORTA XBYTE 0 xFFC0 absacc.h是C51中絕對地址訪問函數(shù)的頭文件,將PORTA定義為外部I/O口,地址為 FFC0H,長度為8位。 一旦在頭文件或程序中對這些片外I/O口進(jìn)行定義后,在程序中就可以自由使用變量名與其實(shí)際地址的聯(lián)系,以便使程序員能用軟件模擬MCS-51的硬件操作。單片機(jī)C語言應(yīng)用程序設(shè)計(jì)

21、 (1) 位變量C51定義。使用C51編程時,定義了位變量后,就可以用定義了的變量來表示MCS-51的位尋址單元。 位變量的C51定義的一般語法格式如下: 位類型標(biāo)識符(bit) 位變量名; 例如:bit direction_bit ;/* 把direction_bit定義為位變量 */bit look_pointer ;/* 把look_pointer定義為位變量 */1.6 位變量的位變量的C51定義定義單片機(jī)C語言應(yīng)用程序設(shè)計(jì) (2) 函數(shù)可包含類型為bit的參數(shù),也可以將其作為返回值。例如: bit func(bit b0, bit b1) /* 變量b0,b1作為函數(shù)的參數(shù) */ r

22、eturn (b1); /* 變量b1作為函數(shù)的返回值 */ 注意,使用(#pragma disable)或包含明確的寄存器組切換(using n)的函數(shù)不能返回位值,否則編輯器將會給出一個錯誤信息。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) (3) 對位變量定義的限制。位變量不能定義成一個指針,如不能定義:bit * bit_pointer。不存在位數(shù)組,如不能定義:bit b_array 。 在位定義中,允許定義存儲類型,位變量都被放入一個位段,此段總位于MCS-51片內(nèi)的RAM區(qū)中。因此,存儲類型限制為data和idata,如果將位變量的存儲類型定義成其它存儲類型都將編譯出錯。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 例

23、例1 先定義變量的數(shù)據(jù)類型和存儲類型:bdata int ibase; /* 定義ibase為bdata整型變量 */bdata char bary4;/* bary4定義為bdata字符型數(shù)組 */然后可使用sbit定義可獨(dú)立尋址訪問的對象位:sbit mybit0 = ibase0 ;/* mybit0定義為ibase的第0位 */sbit mybit15 = ibase15;/* mybit0定義為ibase的第15位 */sbit Ary07 = bary07 ;/* Ary07定義為abry0的第7位 */sbit Ary37 = bary37 ;/* Ary37定義為abry3的第

24、7位 */單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 對象ibase和bary也可以字節(jié)尋址: ary37=0; /* bary3的第7位賦值為0 */ bary3=a; /* 字節(jié)尋址,bary3 賦值為a */ sbit定義要位尋址對象所在字節(jié)基址對象的存儲類型為bdata,否則只有絕對的特殊位定義(sbit)是合法的。操作符后的最大值依賴于指定的基類型,對于char/uchar而言是07,對于int/uint而言是015,對于long/ulong而言是031。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.7 C51構(gòu)造數(shù)據(jù)類型構(gòu)造數(shù)據(jù)類型 1基于存儲器的指針基于存儲器的指針 基于存儲器的指針以存儲器類型為參量,它在編譯時

25、才被確定。因此,為指針選擇存儲器的方法可以省掉,以便這些指針的長度為一個字節(jié)(idata *,data *,pdata *)或2個字節(jié)(code *,xdata *)。編譯時,這類操作一般被行內(nèi)(inline)編碼,而無需進(jìn)行庫調(diào)用。 基于存儲器的指針定義舉例: char xdata *px;單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 在xdata存儲器中定義了一個指向字符型(char)的指針變量px。指針自身在默認(rèn)存儲區(qū)(決定于編譯模式),長度為2個字節(jié)(值為00 xFFFF)。 char xdata *data pdx; 除了明確定義指針位于MCS-51內(nèi)部存儲區(qū)(data)外,其它與上例相同,它與編譯模式

26、無關(guān)。 data char xdata *pdx;單片機(jī)C語言應(yīng)用程序設(shè)計(jì) struct time char hour ; char min; char sec; struct time xdata *pxtime; 在結(jié)構(gòu)struct time中,除了其它結(jié)構(gòu)成員外,還包含有一個具有和struct time相同的指針pxtime,time位于外部數(shù)據(jù)存儲器(xdata),指針pxtime具有兩個字節(jié)長度。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) struct time idata *ptime ; 這個聲明定義了一個位于默認(rèn)存儲器中的指針,它指向結(jié)構(gòu)time,time位于idata存儲器中,結(jié)構(gòu)成員可以通過

27、MCS-51的R0或R1 進(jìn)行間接訪問,指針ptime為1個字節(jié)長。 ptimepxtimehour = 12; 使用上面的關(guān)于struct time和struct idata *ptime的定義,指針pxtime被從結(jié)構(gòu)中間接調(diào)用,它指向位于xdata存儲器中的time結(jié)構(gòu)。結(jié)構(gòu)成員hour被賦值為12。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2一般指針一般指針 一般指針包括3個字節(jié):1個字節(jié)存儲類型和2個字節(jié)偏移地址,即地址+0+1+2內(nèi)容存儲器類型偏移地址高位字節(jié)偏移地址低位字節(jié)其中,第一字節(jié)代表了指針的存儲器類型,存儲器類型編碼如下:存儲器類型idataxdatapdatadatacode值1234

28、5單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 例如,以xdata類型的0 x1234地址為指針可以表示如下:地址+0+1+2內(nèi)容0 x020 x120 x34 當(dāng)用常數(shù)作指針時,必須注意正確定義存儲器類型和偏移量。 例如,將常數(shù)值0 x41寫入地址為0 x8000的外部數(shù)據(jù)存儲器。 #define XBYTE ( (char *) 0 x20000L) XBYTE0 x8000 = 0 x41 ; 其中,XBYTE被定義為(char *)0 x20000L,0 x20000L為一般指針,其存儲類型為2,偏移量為0000H,這樣XBYTE成為指向xdata零地址的指針。而XBYTE8000則是外部數(shù)據(jù)存儲器的0

29、x8000絕對地址。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.8 模塊化程序開發(fā)過程模塊化程序開發(fā)過程圖圖7.4 程序開發(fā)過程程序開發(fā)過程 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.8.1 混合編程混合編程1命名規(guī)則命名規(guī)則表表1.5 函數(shù)名的轉(zhuǎn)換函數(shù)名的轉(zhuǎn)換說 明符號名轉(zhuǎn) 換 規(guī) 則void func(void)FUNC無參數(shù)傳遞或不含寄存器參數(shù)的函數(shù)名不作改變轉(zhuǎn)入目標(biāo)文件中,名字只是簡單地轉(zhuǎn)換為大寫形式void func(void)_FUNC帶寄存器參數(shù)的函數(shù)名加入“_”字符前綴,表明這類函數(shù)包含寄存器的參數(shù)傳遞void func(void)reentrant_?FUNC對于重入函數(shù)加上“_?”字符串前綴,表明這

30、類函數(shù)包含棧內(nèi)的參數(shù)傳遞單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 例例2 用匯編語言編寫函數(shù)toupper,參數(shù)傳遞發(fā)生在寄存器R7中。UPPER SEGMENT CODE ;程序段PUBLIC _TOUPPER ;入口地址PSEG UPPER ; 程序段_TOUPPER: MOV A,R7 ;從R7中取參數(shù) CJNE A,# a,$+3 JC UPPERET CJNE A, # z+1 ,$+3 JNC UPPERET CLR ACC ,5 UPPERET: MOV R7 ,A ;返回值放在R7中 RET ;返回到C單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2參數(shù)傳遞規(guī)則參數(shù)傳遞規(guī)則表表1.6 參數(shù)傳遞的寄存器選擇參數(shù)傳遞

31、的寄存器選擇參數(shù)類型charintlong ,float一般指針第1個參數(shù)R7R6, R7R4R7R1,R2,R3第2個參數(shù)R5R4, R5R4R7R1,R2,R3第3個參數(shù)R3R2, R3無R1,R2,R3單片機(jī)C語言應(yīng)用程序設(shè)計(jì) func1(int a) a是第一個參數(shù),在R6,R7中傳遞。 func2 (int b, int c, int *d ) b是第一個參數(shù),在R6,R7中傳遞;c是第二個參數(shù),在R4,R5中傳遞;d是第三個參數(shù),在R1,R2,R3中傳遞。 func3(long e , long f ) e是第一個參數(shù),在R4R7中傳遞;f是第二個參數(shù),不能在寄存器中傳遞,只能在參

32、數(shù)傳遞段中傳遞。 func4(float g , char h ) g是第一個參數(shù),在R4R7中傳遞;h是第二個參數(shù),必須在參數(shù)傳遞段中傳遞。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 表表1.7 函數(shù)返回值的寄存器函數(shù)返回值的寄存器返 回 值寄 存 器說 明bitC進(jìn)位標(biāo)位(unsigned) charR7 (unsigned) intR6,R7高位字節(jié)在R6,低位字節(jié)在R7(unsigned) longR4R7高位字節(jié)在R4,低位字節(jié)在R7floatR4R732位IEEE格式,指數(shù)和符號位在R7指針R1,R2,R3R3放存儲器類型,高位在R2,低位在R1單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 在匯編子程序中,當(dāng)前選擇的寄

33、存器組及寄存器ACC、B、DPTR和PSW都可能改變。當(dāng)被C調(diào)用時,必須無條件地假設(shè)這些寄存器的內(nèi)容已被破壞。如果已在連接/定位程序時選擇了覆蓋,那么每個匯編子程序包含一個單獨(dú)的程序段是必要的,因?yàn)樵诟采w過程中,函數(shù)間參量通過子程序各自的段參量計(jì)算。匯編子程序的數(shù)據(jù)區(qū)甚至可包含在覆蓋部分中,但應(yīng)注意下面兩點(diǎn): (1) 所有段名必須以C51類似的方法建立。 (2) 每個有局部變量的匯編程序必須指定自己的數(shù)據(jù)段,這個數(shù)據(jù)段只能為其它函數(shù)訪問作參數(shù)傳遞用。所有參數(shù)一個接一個被傳遞,由其它函數(shù)計(jì)算的結(jié)果保存入棧。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.8.2 覆蓋和共享覆蓋和共享 1覆蓋覆蓋 單片機(jī)片內(nèi)存儲空

34、間有限,連接器/定位器通常重新啟用程序不再用的位置。這就是說,若一個程序不再調(diào)用,也不由其它程序調(diào)用(甚至間接調(diào)用),那么在其它程序執(zhí)行完之前,這個程序不再運(yùn)行。這個程序的變量可以放在與其它程序完全相同的RAM空間,很像可重用的寄存器。這種技術(shù)就是覆蓋。在匯編中直接通過手工完成的這些空間分配,C語言中可以由連接器自動管理。若有幾個不相關(guān)聯(lián)的程序時,它可以使RAM單元比手工考慮要用的少。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2共享共享1) 共享變量類 型匯 編 語 言C 語 言動態(tài)變量 y( )int x;靜態(tài)變量 static int x;公用變量PUBLIC XX:ds 2Int x;外部變量EXTER

35、N DATA(X)MOV DPTR,# Xextern int;靜態(tài)子程序/函數(shù)Y:static y( ) ;公共子程序/函數(shù)PUBLIC YY:y( ) ;外部子程序/函數(shù)EXTERN CODE(Y)LCALL Yy( )單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2) 共享函數(shù)/子程序 C中函數(shù)若是全局的(公用的),可以放在調(diào)用的函數(shù)之后。若函數(shù)是模塊專用的,它可以定義為靜態(tài)函數(shù),這樣它不能被其它模塊調(diào)用。C語言的ANSI標(biāo)準(zhǔn)建議所有函數(shù)在主函數(shù)前要有原型(進(jìn)行說明),然后實(shí)際函數(shù)可在主函數(shù)之后或其它模塊中。這符合自頂向下編程的概念。 匯編語言中,子程序使用標(biāo)號可在給定模塊的任何位置。匯編器首先掃描得到所有

36、的符號名,然后值就可填入LCALL或LJMP。一個模塊或另一模塊共享子程序,一個使用PUBLIC而另一個使用EXTERN。當(dāng)指定為EXTERN,符號類型(CODE,DATA,XDATA,IDATA,BIT或NUMBER)必須特別加以指定,以便連接器可以確定放在一起的正確類型。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 1.8.3 庫和連接器庫和連接器/定位器定位器 1. 庫庫表表1.9 Franklin C51的編譯庫的編譯庫庫說 明C51S.LIBSMALL模式,無浮點(diǎn)運(yùn)算C51FPS.LIB浮點(diǎn)數(shù)學(xué)運(yùn)算庫(SMALL模式)C51C.LIBCOMPACT模式,無浮點(diǎn)運(yùn)算C51FPC.LIB浮點(diǎn)運(yùn)算庫(COMP

37、ACT模式)C51L.LIBLARGE模式,無浮點(diǎn)運(yùn)算C51FPL.LIB浮點(diǎn)運(yùn)算庫(LARGE模式)單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2連接器連接器/定位器定位器 1) 組合程序模塊 將幾個不同程序模塊組合為一個模塊,并自動從庫中挑選模塊嵌入目標(biāo)文件。輸入文件按命令行中出現(xiàn)的順序處理。通常的程序模塊是由C51編譯器或A51宏匯編生成的可重入的目標(biāo)文件。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 2) 組合段 將具有相同段名的可重定位段組合成單一的段。在一個程序模塊中定義的一個段成為部分段。一個部分段在源文件中以下列形式指定: (1) 名字 每個重定位段有一個名字,它可與來自其它模塊的同名的可重定位段組合。絕對段沒有名

38、字。 (2) 類型 類型表明段所屬的地址空間CODE,XDATA,DATA或BIT。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) (3) 定位方式 可重定位段的定位方式有PAGE,INPAGE,INBLOCK,BITADD RESSABLE或UNIT。INPAGE表明段必須放入一頁(高8位地址相同)中以使用短轉(zhuǎn)移和調(diào)用指令。INBLOCK段應(yīng)使用ACALL,必須放在2048字節(jié)塊中。因?yàn)闆]有連接器可以靈活地判知調(diào)用和轉(zhuǎn)移是否在塊內(nèi)。可重定位的其它限制是:PAGE-不能超過256字節(jié);BITADDRESSABLE-必須放在可位尋址的內(nèi)部RAM空間;UNIT-允許段從任意字節(jié)開始(對位變量是位)。 (4) 長度 一

39、個段的長度。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) (5) 基址 段的首址。對于絕對段,地址由匯編器賦予,對于可重定位段,地址由L51決定。在處理程序模塊時,L51自動產(chǎn)生段表(MAP),該表包含了每個段的類型、基址、長度、可重定位性和名字。 L51自動將所具有相同名字的所有部分段組合到單一可重定位段中。例如,三個程序模塊包含字段VAR,在組合時,三個段的長度相加,從而組合段的長度也增加了。對組合段有下列規(guī)則: 所有具有相同名的部分段必須有相同類型(CODE,DATA,IDATA,XDATA或BIT)。 組合段的長度不能超過存儲區(qū)的物理長度。 每個組合的部分段的定位方法也必須相同。 絕對段相互不組合,它們被

40、直接拷貝到輸出文件。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 3) 存儲器分配存儲器分配物理存儲區(qū)最大長度地址區(qū)段類型程序64 KB00FFFFHCODE外部數(shù)據(jù)64 KB00FFFFHXDATA直接尋址片內(nèi)數(shù)據(jù)128字節(jié)07FHDATA間接尋址片內(nèi)數(shù)據(jù)256字節(jié)00FFHIDATA片內(nèi)數(shù)據(jù)的位空間128位07FHBIT表1.10 MCS-51系列的物理存儲區(qū)單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 4) 采用覆蓋技術(shù)使用數(shù)據(jù)存儲器 通過采用一定的覆蓋技術(shù),MCS-51系列少量的片內(nèi)數(shù)據(jù)存儲器可由L51有效地使用。由C51編譯器或是A51匯編器生成的參數(shù)和局部變量(若使用它們的函數(shù)不相互調(diào)用)可在存儲器中覆蓋。這樣,所用的存

41、儲器得到相當(dāng)程度地減少。 為完成數(shù)據(jù)覆蓋,L51分析所有不同函數(shù)間的調(diào)用,使用該信息可以確定哪個數(shù)據(jù)和位段可被覆蓋。使用控制參數(shù)OVERLAY和NOOVERLAY可允許或禁止覆蓋。OVERLAY是默認(rèn)值,用它可產(chǎn)生非常緊湊的數(shù)據(jù)區(qū)。 單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 5) 決定外部參考地址 具有相同名的外部符號(EXTERN)和公用符號(PUBLIC)被確定后,外部符號指向其它模塊中的地址。一個已聲明的外部符號用具有相同名字的功用符號確定,外部參考地址由其公共參考地址確定。這還與類型(DATA,IDATA,XDATA,CODE,BIT或NUMBER)有關(guān),如果類型不符或未發(fā)現(xiàn)外部符號參考地址的公用符號,則會產(chǎn)生錯誤。公用符號的絕對地址在段定位后決定。單片機(jī)C語言應(yīng)用程序設(shè)計(jì) 6) 絕對地址計(jì)算 定義絕對地址并計(jì)算可重定位段的地址。在段分配和外部公用參考地址處理完后,程序模塊中所有可重定位地址和外部地址要進(jìn)行計(jì)算,此時生成的目標(biāo)文件中的符號信息(DEBUG)被改變以反映新的

溫馨提示

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

評論

0/150

提交評論