版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第7章 單片機的C語言應用程序設計 第7章 單片機的C語言應用程序設計 7.1 C語言與語言與MCS-517.2 C51數據類型及在數據類型及在MCS-51中的存儲方式中的存儲方式7.3 C51數據的存儲類型與數據的存儲類型與MCS-51存儲結構存儲結構7.4 MCS-51特殊功能寄存器特殊功能寄存器(SFR)的的C51定義定義7.5 MCS-51并行接口的并行接口的C51定義定義7.6 位變量的位變量的C51定義定義7.7 C51構造數據類型構造數據類型7.8 模塊化程序開發(fā)過程模塊化程序開發(fā)過程7.9 MCS-51內部資源使用的內部資源使用的C語言編程語言編程7.10 MCS-51片外擴展
2、的片外擴展的C語言編程語言編程7.11 頻率量測量的頻率量測量的C語言編程語言編程7.12 MCS-51機間通信的機間通信的C語言編程語言編程7.13 鍵盤和數碼顯示人機交互的鍵盤和數碼顯示人機交互的C語言編程語言編程第7章 單片機的C語言應用程序設計 7.1 C語言與語言與MCS51 用匯編程序設計MCS51系列單片機應用程序時,必須要考慮其存儲器結構,尤其必須考慮其片內數據存儲器與特殊功能寄存器正確、合理的使用以及按實際地址處理端口數據。用C語言編寫MCS51單片機的應用程序,雖然不像用匯編語言那樣具體地組織、分配存儲器資源和處理端口數據,但在C語言編程中,對數據類型與變量的定義,必須要與
3、單片機的存儲結構相關聯,否則編譯器不能正確地映射定位。用C語言編寫單片機應用程序與編寫標準的C語言程序的不同之處就在于根據單片機存儲結構及內部資源定義相應的C語言中的數據類型和變量,其它的語法規(guī)定、程序結構及程序設計方法都與標準的C語言程序設計相同。 第7章 單片機的C語言應用程序設計 用C語言編寫的應用程序必須經單片機的C語言編譯器(簡稱C51),轉換生成單片機可執(zhí)行的代碼程序。支持MCS51系列單片機的C語言編譯器有很多種。如American Automation、Auocet、BSO/TASKING、DUNFIELD SHAREWARE、KEIL/Franklin等。其中KEIL/Fra
4、nklin以它的代碼緊湊和使用方便等特點優(yōu)于其它編譯器。本章是針對這種編譯器介紹 MCS51單片機C語言程序設計。 第7章 單片機的C語言應用程序設計 7.2 C51數據類型及在數據類型及在MCS-51中的存儲方式中的存儲方式7.2.1 C51的數據類型的數據類型 Franklin C51編譯器具體支持的數據類型有:位型(bit)、無符號字符(unsigned char)、有符號字符(singed char)、無符號整型(unsigned int )、有符號整型(signed int )、無符號長整型(unsigned long )、有符號長整型(signed long )、浮點型(float
5、)和指針類型等。第7章 單片機的C語言應用程序設計 表表7.1 Franklin C51的數據類型的數據類型數據類型長度(bit)長度(byte)值域bit110,1unsigned char810255signed char81128127unsigned int 162065535signed int 1623276832767unsigned long32404294967295signed long 32421474836482147483647float 3241.176E383.40E+38(6位數字)double6481.176E383.40E+38(10位數字)一般指針243存
6、儲空間065535第7章 單片機的C語言應用程序設計 7.2.2 C51數據在數據在MCS-51中的存儲方式中的存儲方式 位變量(bit):與MCS-51硬件特性操作有關的可以定義成位變量。位變量必須定位在MCS-51單片機片內RAM的位尋址空間中。 字符變量(char):字符變量的長度為1 byte即8位。這很合適MCS-51單片機,因為MCS-51單片機每次可處理8位數據。對于無符號變量(unsigned char)的值域范圍是0255。對于有符號字符變量(signed char),最具有重要意義的位是最高位上的符號標志位(msb)。此位為1代表負,為0代表正。有符號字符變量和無符號字符變
7、量在表示0127的數值時,其含義是一樣的,都是00 x7F。負數一般用補碼表示,即用11111111表示-1, 用11111110表示-2。當進行乘除法運算時,符號問題就變得十分復雜,而C51編譯器會自動地將相應的庫函數調入程序中來解決這個問題。第7章 單片機的C語言應用程序設計 整型變量(int): 整型變量的長度為16位。與8080和8086 CPU系列不同,MCS-51系列單片機將int型變量的高位字節(jié)數存放在低地址字節(jié)中,低位字節(jié)數存放在高地址字節(jié)中。有符號整型變量(signed int)也使用msb位作符號標志位,并使用二進制補碼表示數值??芍苯邮褂脦追N專用的機器指令來完成多字節(jié)的加
8、、減、乘、除運算。整型變量值0 x1234以圖7.1所示的方式存放在內存中。第7章 單片機的C語言應用程序設計 圖7.1 整型數的存儲結構 0 x120 x34+0+1地址 0 x120 x340 x560 x78.+0+1+2+3地址 圖7.2 長整型變量的存儲結構 第7章 單片機的C語言應用程序設計 浮點型變量(float): 浮點型變量為32位,占4個字節(jié),許多復雜的數學表達式都采用浮點變量數據類型。應用符號位表示數的符號,用階碼和尾數表示數的大小。 用它們進行任何數學運算都需要使用由編譯器決定的各種不同效率等級的庫函數。Franklin C51的浮點變量數據類型的使用格式與IEEE-7
9、54標準有關,具有24位精度,尾數的高位始終為1,因而不保存,位的分布如下: 1位符號位。 8位指數位。 23位尾數。 第7章 單片機的C語言應用程序設計 符號位是最高位,尾數為低23位,內存中按字節(jié)存儲順序如下:地址地址+0+1+2+3內容內容MMMMMMMMMMMMMMMMEMMMMMMMSEEEEEEE 其中,S為符號位,1表示負,0表示正;E為階碼;M為23位尾數,最高位為1。 浮點變量值 -12.5的十進制為:0 xC1480000,它按圖7.3所示方式存于內存中。第7章 單片機的C語言應用程序設計 0 x000 x000 x480 xC1.+0+1+2+3地址 圖7.3 浮點數的存
10、儲結構 第7章 單片機的C語言應用程序設計 在編程時,如果只強調運算速度而不進行負數運算時,最好采用無符號(unsigned)格式。 無符號字符類型的使用:無論何時,應盡可能使用無符號字符變量,因為它能直接被MCS-51所接受?;谕瑯拥脑?,也應盡量使用位變量。有符號字符變量雖然也只占用一個字節(jié),但需要進行額外的操作來進行測試代碼的符號位。這無疑會降低代碼效率。第7章 單片機的C語言應用程序設計 使用簡化形式定義數據類型。其方法是在源程序開頭使用#define語句自定義簡化的類型標識符。例如:#define uchar unsigned char #define uint unsigned
11、int 這樣,在編程中,就可以用uchar代替unsigned char,用uint代替unsigned int來定義變量。第7章 單片機的C語言應用程序設計 7.3 C51數據的存儲類型與數據的存儲類型與MCS-51存儲結構存儲結構表表 7.2 C51存儲類型與存儲類型與MCS-51存儲空間的對應關系存儲空間的對應關系存儲類型與存儲空間的對應關系 data 直接尋址片內數據存儲區(qū),訪問速度快(128字節(jié)) bdata 可位尋址片內數據存儲區(qū),允許位與字節(jié)混合訪問(16字節(jié)) idata 間接尋址片內數據存儲區(qū),可訪問片內全部RAM地址空間(256字節(jié)) pdata 分頁尋址片外數據存儲區(qū)(2
12、56字節(jié))由MOV Ri訪問(i=0,1) xdata 片外數據存儲區(qū)(64 KB)由MOVX DPTR訪問 code 程序存儲器64 KB空間,由MOVC DPTR訪問第7章 單片機的C語言應用程序設計 表表7.3 C51存儲類型及其數據長度和值域存儲類型及其數據長度和值域存儲類型長度(bit)長度(byte)值域范圍data810255idata810255pdata810255xdata162065 535code162065 535第7章 單片機的C語言應用程序設計 帶存儲類型的變量的定義的一般格式為 數據類型 存儲類型 變量名帶存儲類型的變量定義舉例:char data var1;b
13、it bdata flags;float idata x,y,z;unsigned int pdata var2;unsigned char vector34;第7章 單片機的C語言應用程序設計 表表 7.4 存儲模式說明存儲模式說明存儲模式說 明SMALL默認的存儲類型是data,參數及局部變量放入可直接尋址片內RAM的用戶區(qū)中(最大128字節(jié))。另外所有對象(包括堆棧),都必須嵌入片內RAM。棧長很關鍵,因為實際棧長依賴于函數嵌套調用層數COMPACT默認的存儲類型是pdata,參數及局部變量放入分頁的外部數據存儲區(qū),通過R0或R1間接訪問,??臻g位于片內數據存儲區(qū)中LARGE默認的存儲類
14、型是xdata,參數及局部變量直接放入片外數據存儲區(qū),使用數據指針DPTR來進行尋址。用此數據指針進行訪問效率較低,尤其對兩個或多個字節(jié)的變量,這種數據類型的訪問機制直接影響代碼的長度第7章 單片機的C語言應用程序設計 7.4 MCS-51特殊功能寄存器特殊功能寄存器(SFR)的的C51定義定義 MCS-51單片機中,除了程序計數器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器(SFR),分散在片內RAM區(qū)的高128字節(jié)中,地址范圍為80H0FFH。SFR中有11個寄存器具有位尋址能力,它們的字節(jié)地址都能被8整除,即字節(jié)地址是以8或0為尾數的。 為了能直接訪問這些SFR,Fran
15、klin C51提供了一種自主形式的定義方法,這種定義方法與標準C語言不兼容,只適用于對MCS-51系列單片機進行C語言編程。特殊功能寄存器C51定義的一般語法格式如下:sfr sfr-name = int constant;第7章 單片機的C語言應用程序設計 sfr是定義語句的關鍵字,其后必須跟一個MSC-51單片機真實存在的特殊功能寄存器名,=后面必須是一個整型常數,不允許帶有運算符的表達式,是特殊功能寄存器sfr-name的字節(jié)地址,這個常數值的范圍必須在SFR地址范圍內,位于0 x800 xFF。例如:sfr SCON=0 x98; /* 串口控制寄存器地址98H */sfr TMOD
16、=0 x89;/* 定時器/計數器方式控制寄存器地址89H */第7章 單片機的C語言應用程序設計 MCS-51系列單片機的特殊功能寄存器的數量與類型不盡相同,因此建議將所有特殊的sfr定義放入一個頭文件中,該文件應包括MCS-51單片機系列機型中的SFR定義。C51編譯器的reg51.h頭文件就是這樣一個文件。 在新的MCS-51系列產品中,SFR在功能上經常組合為16位值,當SFR的高字節(jié)地址直接位于低字節(jié)之后時,對16位SFR的值可以直接進行訪問。例如52子系列的定時器/計數器2就是這種情況。為了有效地訪問這類SFR,可使用關鍵字sfr16來定義,其定義語句的語法格式與8位SFR相同,只
17、是=后面的地址必須用16位SFR的低字節(jié)地址,即低字節(jié)地址作為sfr16的定義地址。第7章 單片機的C語言應用程序設計 例如: sfr16 T2 = 0 xCC /*定時器/計數器2:T2低8位地址為0CCH,T2高8位地址為0CDH*/ 這種定義適用于所有新的16位SFR,但不能用于定時器/計數器0和1。 對于位尋址的SFR中的位,C51的擴充功能支持特殊位的定義,像SFR一樣不與標準C兼容,使用sbit來定義位尋址單元。第7章 單片機的C語言應用程序設計 第一種格式: sbit bit-name = sfr-nameint constant; sbit是定義語句的關鍵字,后跟一個尋址位符號
18、名(該位符號名必須是MCS-51單片機中規(guī)定的位名稱),=后的sfr-name必須是已定義過的SFR的名字,后的整常數是尋址位在特殊功能寄存器sfr-name中的位號,必須是07范圍中的數。例如: sfr PSW=0 xD0 ; /* 定義PSW寄存器地址為D0H */ sbit OV=PSW2 ; /* 定義OV位為PSW.2,地址為D2H */ sbit CY=PSW7 ; /* 定義CY位為PSW.7,地址為D7H */第7章 單片機的C語言應用程序設計 第二種格式:sbit bit-name = int constantint constant; =后的int constant為尋址地
19、址位所在的特殊功能寄存器的字節(jié)地址,符號后的int constant為尋址位在特殊功能寄存器中的位號。例如: sbit OV=0XD02 ;/* 定義OV位地址是D0H字節(jié)中的第2位 */ sbit CY=0XD07 ;/* 定義CY位地址是D0H字節(jié)中的第7位 */第7章 單片機的C語言應用程序設計 第三種格式:sbit bit-name = int constant; =后的int constant為尋址位的絕對位地址。例如: sbit OV=0XD2 ;/* 定義OV位地址為D2H */ sbit CY=0XD7 ;/* 定義CY位地址為D7H */ 特殊功能位代表了一個獨立的定義類,不
20、能與其它位定義和位域互換。第7章 單片機的C語言應用程序設計 7.5 MCS-51并行接口的并行接口的C51定義定義 MCS-51系列單片機并行I/O接口除了芯片上的4個I/O口(P0 P3)外,還可以在片外擴展I/O口。MCS-51單片機I/O口與數據存儲器統(tǒng)一編址,即把一個I/O口當作數據存儲器中的一個單元來看待。 使用C51進行編程時,MCS-51片內的I/O口與片外擴展的I/O可以統(tǒng)一在一個頭文件中定義,也可以在程序中(一般在開始的位置)進行定義,其定義方法如下: 對于MCS-51片內I/O口按特殊功能寄存器方法定義。例如:sfr P0=0 x80 ; /* 定義P0口,地址為80H
21、*/sfr P1=0 x90 ; /* 定義P1口,地址為90H */第7章 單片機的C語言應用程序設計 對于片外擴展I/O口,則根據硬件譯碼地址,將其視作為片外數據存儲器的一個單元,使用#define語句進行定義。例如#include #define PORTA XBYTE 0 xFFC0 absacc.h是C51中絕對地址訪問函數的頭文件,將PORTA定義為外部I/O口,地址為 FFC0H,長度為8位。 一旦在頭文件或程序中對這些片外I/O口進行定義后,在程序中就可以自由使用變量名與其實際地址的聯系,以便使程序員能用軟件模擬MCS-51的硬件操作。第7章 單片機的C語言應用程序設計 (1)
22、 位變量C51定義。使用C51編程時,定義了位變量后,就可以用定義了的變量來表示MCS-51的位尋址單元。 位變量的C51定義的一般語法格式如下: 位類型標識符(bit) 位變量名; 例如:bit direction_bit ;/* 把direction_bit定義為位變量 */bit look_pointer ;/* 把look_pointer定義為位變量 */7.6 位變量的位變量的C51定義定義第7章 單片機的C語言應用程序設計 (2) 函數可包含類型為bit的參數,也可以將其作為返回值。例如: bit func(bit b0, bit b1) /* 變量b0,b1作為函數的參數 */
23、return (b1); /* 變量b1作為函數的返回值 */ 注意,使用(#pragma disable)或包含明確的寄存器組切換(using n)的函數不能返回位值,否則編輯器將會給出一個錯誤信息。第7章 單片機的C語言應用程序設計 (3) 對位變量定義的限制。位變量不能定義成一個指針,如不能定義:bit * bit_pointer。不存在位數組,如不能定義:bit b_array 。 在位定義中,允許定義存儲類型,位變量都被放入一個位段,此段總位于MCS-51片內的RAM區(qū)中。因此,存儲類型限制為data和idata,如果將位變量的存儲類型定義成其它存儲類型都將編譯出錯。第7章 單片機的
24、C語言應用程序設計 例例1 先定義變量的數據類型和存儲類型:bdata int ibase; /* 定義ibase為bdata整型變量 */bdata char bary4;/* bary4定義為bdata字符型數組 */然后可使用sbit定義可獨立尋址訪問的對象位:sbit mybit0 = ibase0 ;/* mybit0定義為ibase的第0位 */sbit mybit15 = ibase15;/* mybit0定義為ibase的第15位 */sbit Ary07 = bary07 ;/* Ary07定義為abry0的第7位 */sbit Ary37 = bary37 ;/* Ary3
25、7定義為abry3的第7位 */第7章 單片機的C語言應用程序設計 對象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。第7章 單片機的C語言應用程序設計 7.7 C51構造數據類型構造數據類型 1基于存儲器的指針基于存儲器的指針 基于
26、存儲器的指針以存儲器類型為參量,它在編譯時才被確定。因此,為指針選擇存儲器的方法可以省掉,以便這些指針的長度為一個字節(jié)(idata *,data *,pdata *)或2個字節(jié)(code *,xdata *)。編譯時,這類操作一般被行內(inline)編碼,而無需進行庫調用。 基于存儲器的指針定義舉例: char xdata *px;第7章 單片機的C語言應用程序設計 在xdata存儲器中定義了一個指向字符型(char)的指針變量px。指針自身在默認存儲區(qū)(決定于編譯模式),長度為2個字節(jié)(值為00 xFFFF)。 char xdata *data pdx; 除了明確定義指針位于MCS-51內
27、部存儲區(qū)(data)外,其它與上例相同,它與編譯模式無關。 data char xdata *pdx;第7章 單片機的C語言應用程序設計 struct time char hour ; char min; char sec; struct time xdata *pxtime; 在結構struct time中,除了其它結構成員外,還包含有一個具有和struct time相同的指針pxtime,time位于外部數據存儲器(xdata),指針pxtime具有兩個字節(jié)長度。第7章 單片機的C語言應用程序設計 struct time idata *ptime ; 這個聲明定義了一個位于默認存儲器中的指
28、針,它指向結構time,time位于idata存儲器中,結構成員可以通過MCS-51的R0或R1 進行間接訪問,指針ptime為1個字節(jié)長。 ptimepxtimehour = 12; 使用上面的關于struct time和struct idata *ptime的定義,指針pxtime被從結構中間接調用,它指向位于xdata存儲器中的time結構。結構成員hour被賦值為12。第7章 單片機的C語言應用程序設計 2一般指針一般指針 一般指針包括3個字節(jié):1個字節(jié)存儲類型和2個字節(jié)偏移地址,即地址+0+1+2內容存儲器類型偏移地址高位字節(jié)偏移地址低位字節(jié)其中,第一字節(jié)代表了指針的存儲器類型,存儲
29、器類型編碼如下:存儲器類型idataxdatapdatadatacode值12345第7章 單片機的C語言應用程序設計 例如,以xdata類型的0 x1234地址為指針可以表示如下:地址+0+1+2內容0 x020 x120 x34 當用常數作指針時,必須注意正確定義存儲器類型和偏移量。 例如,將常數值0 x41寫入地址為0 x8000的外部數據存儲器。 #define XBYTE ( (char *) 0 x20000L) XBYTE0 x8000 = 0 x41 ; 其中,XBYTE被定義為(char *)0 x20000L,0 x20000L為一般指針,其存儲類型為2,偏移量為0000H
30、,這樣XBYTE成為指向xdata零地址的指針。而XBYTE8000則是外部數據存儲器的0 x8000絕對地址。第7章 單片機的C語言應用程序設計 7.8 模塊化程序開發(fā)過程模塊化程序開發(fā)過程圖圖7.4 程序開發(fā)過程程序開發(fā)過程 第7章 單片機的C語言應用程序設計 7.8.1 混合編程混合編程1命名規(guī)則命名規(guī)則表表7.5 函數名的轉換函數名的轉換說 明符號名轉 換 規(guī) 則void func(void)FUNC無參數傳遞或不含寄存器參數的函數名不作改變轉入目標文件中,名字只是簡單地轉換為大寫形式void func(void)_FUNC帶寄存器參數的函數名加入“_”字符前綴,表明這類函數包含寄存器
31、的參數傳遞void func(void)reentrant_?FUNC對于重入函數加上“_?”字符串前綴,表明這類函數包含棧內的參數傳遞第7章 單片機的C語言應用程序設計 例例2 用匯編語言編寫函數toupper,參數傳遞發(fā)生在寄存器R7中。UPPER SEGMENT CODE ;程序段PUBLIC _TOUPPER ;入口地址PSEG UPPER ; 程序段_TOUPPER: MOV A,R7 ;從R7中取參數 CJNE A,# a,$+3 JC UPPERET CJNE A, # z+1 ,$+3 JNC UPPERET CLR ACC ,5 UPPERET: MOV R7 ,A ;返回值
32、放在R7中 RET ;返回到C第7章 單片機的C語言應用程序設計 2參數傳遞規(guī)則參數傳遞規(guī)則表表7.6 參數傳遞的寄存器選擇參數傳遞的寄存器選擇參數類型charintlong ,float一般指針第1個參數R7R6, R7R4R7R1,R2,R3第2個參數R5R4, R5R4R7R1,R2,R3第3個參數R3R2, R3無R1,R2,R3第7章 單片機的C語言應用程序設計 func1(int a) a是第一個參數,在R6,R7中傳遞。 func2 (int b, int c, int *d ) b是第一個參數,在R6,R7中傳遞;c是第二個參數,在R4,R5中傳遞;d是第三個參數,在R1,R2
33、,R3中傳遞。 func3(long e , long f ) e是第一個參數,在R4R7中傳遞;f是第二個參數,不能在寄存器中傳遞,只能在參數傳遞段中傳遞。 func4(float g , char h ) g是第一個參數,在R4R7中傳遞;h是第二個參數,必須在參數傳遞段中傳遞。第7章 單片機的C語言應用程序設計 表表7.7 函數返回值的寄存器函數返回值的寄存器返 回 值寄 存 器說 明bitC進位標位(unsigned) charR7 (unsigned) intR6,R7高位字節(jié)在R6,低位字節(jié)在R7(unsigned) longR4R7高位字節(jié)在R4,低位字節(jié)在R7floatR4R7
34、32位IEEE格式,指數和符號位在R7指針R1,R2,R3R3放存儲器類型,高位在R2,低位在R1第7章 單片機的C語言應用程序設計 在匯編子程序中,當前選擇的寄存器組及寄存器ACC、B、DPTR和PSW都可能改變。當被C調用時,必須無條件地假設這些寄存器的內容已被破壞。如果已在連接/定位程序時選擇了覆蓋,那么每個匯編子程序包含一個單獨的程序段是必要的,因為在覆蓋過程中,函數間參量通過子程序各自的段參量計算。匯編子程序的數據區(qū)甚至可包含在覆蓋部分中,但應注意下面兩點: (1) 所有段名必須以C51類似的方法建立。 (2) 每個有局部變量的匯編程序必須指定自己的數據段,這個數據段只能為其它函數訪
35、問作參數傳遞用。所有參數一個接一個被傳遞,由其它函數計算的結果保存入棧。 第7章 單片機的C語言應用程序設計 7.8.2 覆蓋和共享覆蓋和共享 1覆蓋覆蓋 單片機片內存儲空間有限,連接器/定位器通常重新啟用程序不再用的位置。這就是說,若一個程序不再調用,也不由其它程序調用(甚至間接調用),那么在其它程序執(zhí)行完之前,這個程序不再運行。這個程序的變量可以放在與其它程序完全相同的RAM空間,很像可重用的寄存器。這種技術就是覆蓋。在匯編中直接通過手工完成的這些空間分配,C語言中可以由連接器自動管理。若有幾個不相關聯的程序時,它可以使RAM單元比手工考慮要用的少。第7章 單片機的C語言應用程序設計 2共
36、享共享1) 共享變量類 型匯 編 語 言C 語 言動態(tài)變量 y( )int x;靜態(tài)變量 static int x;公用變量PUBLIC XX:ds 2Int x;外部變量EXTERN DATA(X)MOV DPTR,# Xextern int;靜態(tài)子程序/函數Y:static y( ) ;公共子程序/函數PUBLIC YY:y( ) ;外部子程序/函數EXTERN CODE(Y)LCALL Yy( )第7章 單片機的C語言應用程序設計 2) 共享函數/子程序 C中函數若是全局的(公用的),可以放在調用的函數之后。若函數是模塊專用的,它可以定義為靜態(tài)函數,這樣它不能被其它模塊調用。C語言的AN
37、SI標準建議所有函數在主函數前要有原型(進行說明),然后實際函數可在主函數之后或其它模塊中。這符合自頂向下編程的概念。 匯編語言中,子程序使用標號可在給定模塊的任何位置。匯編器首先掃描得到所有的符號名,然后值就可填入LCALL或LJMP。一個模塊或另一模塊共享子程序,一個使用PUBLIC而另一個使用EXTERN。當指定為EXTERN,符號類型(CODE,DATA,XDATA,IDATA,BIT或NUMBER)必須特別加以指定,以便連接器可以確定放在一起的正確類型。第7章 單片機的C語言應用程序設計 7.8.3 庫和連接器庫和連接器/定位器定位器 1. 庫庫表表7.9 Franklin C51的
38、編譯庫的編譯庫庫說 明C51S.LIBSMALL模式,無浮點運算C51FPS.LIB浮點數學運算庫(SMALL模式)C51C.LIBCOMPACT模式,無浮點運算C51FPC.LIB浮點運算庫(COMPACT模式)C51L.LIBLARGE模式,無浮點運算C51FPL.LIB浮點運算庫(LARGE模式)第7章 單片機的C語言應用程序設計 2連接器連接器/定位器定位器 1) 組合程序模塊 將幾個不同程序模塊組合為一個模塊,并自動從庫中挑選模塊嵌入目標文件。輸入文件按命令行中出現的順序處理。通常的程序模塊是由C51編譯器或A51宏匯編生成的可重入的目標文件。第7章 單片機的C語言應用程序設計 2)
39、 組合段 將具有相同段名的可重定位段組合成單一的段。在一個程序模塊中定義的一個段成為部分段。一個部分段在源文件中以下列形式指定: (1) 名字 每個重定位段有一個名字,它可與來自其它模塊的同名的可重定位段組合。絕對段沒有名字。 (2) 類型 類型表明段所屬的地址空間CODE,XDATA,DATA或BIT。 第7章 單片機的C語言應用程序設計 (3) 定位方式 可重定位段的定位方式有PAGE,INPAGE,INBLOCK,BITADD RESSABLE或UNIT。INPAGE表明段必須放入一頁(高8位地址相同)中以使用短轉移和調用指令。INBLOCK段應使用ACALL,必須放在2048字節(jié)塊中。
40、因為沒有連接器可以靈活地判知調用和轉移是否在塊內??芍囟ㄎ坏钠渌拗剖牵篜AGE-不能超過256字節(jié);BITADDRESSABLE-必須放在可位尋址的內部RAM空間;UNIT-允許段從任意字節(jié)開始(對位變量是位)。 (4) 長度 一個段的長度。第7章 單片機的C語言應用程序設計 (5) 基址 段的首址。對于絕對段,地址由匯編器賦予,對于可重定位段,地址由L51決定。在處理程序模塊時,L51自動產生段表(MAP),該表包含了每個段的類型、基址、長度、可重定位性和名字。 L51自動將所具有相同名字的所有部分段組合到單一可重定位段中。例如,三個程序模塊包含字段VAR,在組合時,三個段的長度相加,從而
41、組合段的長度也增加了。對組合段有下列規(guī)則: 所有具有相同名的部分段必須有相同類型(CODE,DATA,IDATA,XDATA或BIT)。 組合段的長度不能超過存儲區(qū)的物理長度。 每個組合的部分段的定位方法也必須相同。 絕對段相互不組合,它們被直接拷貝到輸出文件。第7章 單片機的C語言應用程序設計 3) 存儲器分配存儲器分配物理存儲區(qū)最大長度地址區(qū)段類型程序64 KB00FFFFHCODE外部數據64 KB00FFFFHXDATA直接尋址片內數據128字節(jié)07FHDATA間接尋址片內數據256字節(jié)00FFHIDATA片內數據的位空間128位07FHBIT表7.10 MCS-51系列的物理存儲區(qū)第
42、7章 單片機的C語言應用程序設計 4) 采用覆蓋技術使用數據存儲器 通過采用一定的覆蓋技術,MCS-51系列少量的片內數據存儲器可由L51有效地使用。由C51編譯器或是A51匯編器生成的參數和局部變量(若使用它們的函數不相互調用)可在存儲器中覆蓋。這樣,所用的存儲器得到相當程度地減少。 為完成數據覆蓋,L51分析所有不同函數間的調用,使用該信息可以確定哪個數據和位段可被覆蓋。使用控制參數OVERLAY和NOOVERLAY可允許或禁止覆蓋。OVERLAY是默認值,用它可產生非常緊湊的數據區(qū)。 第7章 單片機的C語言應用程序設計 5) 決定外部參考地址 具有相同名的外部符號(EXTERN)和公用符
43、號(PUBLIC)被確定后,外部符號指向其它模塊中的地址。一個已聲明的外部符號用具有相同名字的功用符號確定,外部參考地址由其公共參考地址確定。這還與類型(DATA,IDATA,XDATA,CODE,BIT或NUMBER)有關,如果類型不符或未發(fā)現外部符號參考地址的公用符號,則會產生錯誤。公用符號的絕對地址在段定位后決定。第7章 單片機的C語言應用程序設計 6) 絕對地址計算 定義絕對地址并計算可重定位段的地址。在段分配和外部公用參考地址處理完后,程序模塊中所有可重定位地址和外部地址要進行計算,此時生成的目標文件中的符號信息(DEBUG)被改變以反映新的值。第7章 單片機的C語言應用程序設計 7
44、) 產生絕對目標文件 可執(zhí)行程序以絕對目標格式產生。該絕對目標文件可包含附加的符號信息(DEBUG),從而使符號調試成為可能。符號信息可用參數NODEBUGSYMBOLS,NODEBUGPUBLICS和NODEBUGLINES禁止。輸出文件是可執(zhí)行的,并可由仿真器裝入調試或被OHS51翻譯為Intel HEX格式文件以供EPROM固化。第7章 單片機的C語言應用程序設計 8) 產生映像文件 產生一個反映每個處理步驟的映像文件,它顯示有關連接/定位過程的信息和程序符號,并包含一個公用和外部符號的交叉參考報告。映像文件包含下列信息: 文件名和命令行參數。 模塊的文件名和模塊名。 一個包含段地址、類
45、型、定位方法和名字的存儲器分配表。該表可在命令行中用NOMAP參考禁止。第7章 單片機的C語言應用程序設計 段和符號的所有錯誤列表。列表文件末尾顯示出所有出錯的原因。 一個包含輸入文件中符號信息的符號表。該信息由MODULES,SYMBOLS,PUBLICS和LINES名組成,LINES是C編譯器產生的行號。符號信息可用參數NOSYMBOLS,NOPUBLICS和NOLINES完全或部分禁止。 一個按字母順序排列的有關所有PUBLIC和EXTERN符號的交叉參考報告,其中顯示出符號類型和模塊名。第一個顯示的模塊名是定義了PUBLIC符號的模塊,后面的模塊名是定義了EXTERN符號的模塊。在命令
46、行輸入參數IXREF可產生此報告。 在連接器/定位器運行期間檢測到的錯誤同時顯示在屏幕和文件尾部。第7章 單片機的C語言應用程序設計 7.8.4 程序優(yōu)化程序優(yōu)化 以下選擇對提高程序效率有很大影響: (1) 盡量選擇小存儲模式以避免使用MOVX指令。 (2) 使用大模式(COMPACT/LARGE)應仔細考慮要放在內部數據存儲器的變量要求是經常用的或是用于中間結果的。訪問內部數據存儲器要比訪問外部數據存儲器快得多。內部RAM由寄存器組、位數據區(qū)和其它用戶用“data”類型定義的變量共享。由于內部RAM容量的限制(128256字節(jié),由使用的單片機決定),必須權衡利弊以解決訪問效率和這些對象的數量
47、之間的矛盾。第7章 單片機的C語言應用程序設計 (3) 要考慮操作順序,完成一件事后再做一件事。 (4) 注意程序編寫細則。例如,若使用for(;)循環(huán),DJNZ指令比CJNE指令更有效,可減少重復循環(huán)次數。 (5) 若編譯器不能使用左移和右移完成乘除法,應立即修改,例如,左移為乘2。 (6) 用邏輯AND/&取模比用MOD / %操作更有效。 (7) 因計算機基于二進制,仔細選擇數據存儲器和數組大小可節(jié)省操作。第7章 單片機的C語言應用程序設計 (8) 盡可能使用最小的數據類型,MCS-51系列是8位機,顯然對具有char類型的對象的操作比int或long類型的對象的操作要方便得多。
48、 (9) 盡可能使用unsigned數據類型。MCS-51系列CPU并不直接支持有符號數的運算。因而C51編譯器必須產生與之相關的更多的程序代碼以解決這個問題。 (10) 盡可能使用局部函數變量。編譯器總是嘗試在寄存器里保持局部變量。這樣,將循環(huán)變量(如for和while循環(huán)中的計數變量)說明為局部變量是最好的。使用unsigned char/int的對象通常能獲得最好的結果。第7章 單片機的C語言應用程序設計 7.9 MCS-51內部資源使用的內部資源使用的C語言編程語言編程7.9.1 中斷應用的中斷應用的C語言編程語言編程 C51編譯器支持在C源程序中直接開發(fā)中斷程序。中斷服務程序是通過按
49、規(guī)定語法格式定義的一個函數。 中斷服務程序的函數定義的語法格式如下: 返回值 函數名(參數) interrupt musing n 第7章 單片機的C語言應用程序設計 表表7.11 MCS-51中斷源編號中斷源編號編 號中 斷 源入 口 地 址0外部中斷00003H1定時器/計數器0000BH2外部中斷10013H3定時器/計數器1001BH4串行口中斷0023H第7章 單片機的C語言應用程序設計 using n 選項用于實現工作寄存器組的切換,n是中斷服務子程序中選用的工作寄存器組號(0 3)。在許多情況下,響應中斷時需保護有關現場信息,以便中斷返回后,能使中斷前的源程序從斷點處繼續(xù)正確地執(zhí)
50、行下去。這在MCS-51單片機中,能很方便地利用工作寄存器組的切換來實現。即在進入中斷服務程序前的程序中使用一組工作寄存器,進入中斷服務程序后,由using n切換到另一組寄存器,中斷返回后又恢復到原寄存器組。這樣互相切換的兩組寄存器中的內容彼此都沒有被破壞。第7章 單片機的C語言應用程序設計 圖圖 7.5 擴展多個中斷源擴展多個中斷源 例例3 圖7.5所示是利用優(yōu)先權解碼芯片,在單片機8031的一個外部中斷INT1上擴展多個中斷源的原理電路圖。圖中是以開關閉合來模擬中斷請求信號。當有任一中斷源產生中斷請求,能給8031的INT1引腳送一個有效中斷信號,由P1的低3位可得對應中斷源的中斷號。第
51、7章 單片機的C語言應用程序設計 在中斷服務程序中僅設置標志,并保存I/O口輸入狀態(tài)。Franklin C51編譯器提供定義特定MCS-51系列成員的寄存器頭文件。MCS-51頭文件為reg51.h。C51程序如下: # include unsigned char status; bit flag; void service_int1( ) interrupt 2 using 2 /* INT1中斷服務程序,使用第2組工作寄存器 */ flag=1; /* 設置標志 */ status=p1; /* 存輸入口狀態(tài) */ void main(void) IP=0 x04 ; /* 置INT1為高
52、優(yōu)先級中斷 */ IE=-0 x84 ; /* INT1開中斷,CPU開中斷 */第7章 單片機的C語言應用程序設計 for(; ;) if(flag) /* 有中斷 */ switch(status) /* 根據中斷源分支 */ case 0 : break ; /* 處理IN0 */ case 1 : break ; /* 處理IN1 */ case 2 : break; /* 處理IN2 */ case 3 : break; /* 處理IN3 */ default : ; flag=0 ; /* 處理完成清標志 */ 第7章 單片機的C語言應用程序設計 7.9.2 定時器定時器/計數器計
53、數器(T/C)應用的應用的C語言編程語言編程 例例4 設單片機的fosc=12 MHz晶振,要求在P1.0腳上輸出周期為2 ms的方波。 周期為2 ms的方波要求定時時間隔1 ms,每次時間到P1.0取反。 機器周期=12/fosc=1 s 需計數次數=1000/(12/fosc)=1000/1=1000 由于計數器是加1計數,為得到1000個計數之后的定時器溢出,必須給定時器置初值為-1000(即1000的補數)。第7章 單片機的C語言應用程序設計 (1) 用定時器0的方式1編程,采用查詢方式,程序如下: # include sbit P1_0=P10 ; void main(void) T
54、MOD=0 x01 ; /* 設置定時器1為非門控制方式1*/ TR0=1 ; /* 啟動 T/C0 */ for( ; ;) TH0= -(1000/256) ; /* 裝載計數器初值 */ TL0= -(1000%256) ; do while (!TF0) ; /* 查詢等待TF0置位 */ P1_0=!P1_0; /* 定時時間到P1.0反相 */ TF0=0; /* 軟件清 TF0 */ 第7章 單片機的C語言應用程序設計 (2) 用定時器0的方式1編程,采用中斷方式。程序如下: # include sbit P1_0=P10 ; void time (void) interrupt
55、 1 using 1 /* T/C0中斷服務程序入口 */ P1_0=!P1_0 ; /* P1.0取反 */ TH0= -(1000/256); / * 重新裝載計數初值 */ void main( void ) TMOD=0 x01 ; /* T/C0工作在定時器非門控制方式1 */ P1_0=0; TH0= -(1000/256 ); /* 預置計數初值 */ TL0= -(1000%256) ; EA=1 ; /* CPU中斷開放 */ ET0= 1 ; /* T/C0中斷開放 */ TR0=1 ; /* 啟動T/C0開始定時 */ do while(1) ; /* 等待中斷 */ 第
56、7章 單片機的C語言應用程序設計 例例5 采用10 MHz晶振,在P1.0腳上輸出周期為2.5 s,占空比20%的脈沖信號。 10 MHz晶振,使用定時器最大定時幾十毫秒。取10 ms定時,周期2.5 s需250次中斷,占空比20%,高電平應為50次中斷。 10 ms定時,晶振fosc=10 MHz。 需定時器計數次數=1010310/12=8333# include # define uchar unsigned charuchar period=250;uchar high=50;第7章 單片機的C語言應用程序設計 timer0( )interrupt 1 using 1 /* T/C0中
57、斷服務程序 */TH0= - 8333/256 ; /* 重置計數值 */TL0= - 8333%256 ; if(+time=high)P1=0; /* 高電平時間到變低 */else if (time=period) /* 周期時間到變高 */time=0 ;P1=1 ; 第7章 單片機的C語言應用程序設計 main( ) TMOD=0 x01 ; /* 定時器0方式1 */ TH0= - 8333/256 ;/* 預置計數初值 */ TL0= - 8333%256 ; EA=1; /* 開CPU中斷 */ ET0=1 ; /* 開T/C0中斷 */ TR0=1 ; /* 啟動T/C0 *
58、/ do while(1) ; 第7章 單片機的C語言應用程序設計 圖7.6 中斷服務程序流程圖 第7章 單片機的C語言應用程序設計 產生一個占空比變化脈沖信號的程序,它產生的脈寬調制信號用于電機變速控制。# include # define uchar unsigned char # define uint unsigned int unchar time,status,percent,period;bit one_round;uint oldcount,target=500;void pulse (void) interrupt 1 using 1 /* T/C0中斷服務程序 */ TH0
59、= - 833/256 ; /* 1ms - -10 MHz */第7章 單片機的C語言應用程序設計 TL0= - 833%256 ; ET0=1 ; if (+time=percent) P1=0 ; else if (time= =100 ) time=0 ; P1=1; void tachmeter ( void ) interrupt 2 using 2 /* 外中斷1服務程序 */ union unit word ; struct uchar hi ; uchar lo ; byte ; 第7章 單片機的C語言應用程序設計 newcount ; newcount. byte. hi=
60、TH1; newcount .byte .lo=TL1 ; period=newcount .word - oldcount ; /* 測得周期 */ oldcount=newcount .word ; one_round=1; /* 每轉一圈,引起中斷,設置標志 */ void main ( void ) IP=0 x04 ; /* 置INT1為高位優(yōu)先級 */ TMOD= 0 x11 ; /* T0,T1 16位方式 */ TCON=0 x54 ; /* T0,T1運行,IT1邊沿觸發(fā) */第7章 單片機的C語言應用程序設計 TH1=0;TL1=0; /* 設置初始計數值 */ IE=0 x86 ; /* 允許中斷EX1,ET0 */ for (; ;) if
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版事業(yè)單位聘用合同書(二零二五年度)修訂本3篇
- 2025年水庫水面旅游開發(fā)合作協(xié)議3篇
- 2025年采摘果園休閑農業(yè)項目承包經營合同3篇
- 2025年鐵路旅客承運人服務質量提升與旅客滿意度合同3篇
- 二零二五版跨區(qū)域二手房產權轉移協(xié)助合同
- 2025版烏笑與配偶離婚后子女教育費用支付調整協(xié)議3篇
- 萬科物業(yè)2024全年服務細則協(xié)議版
- 三方借款協(xié)作協(xié)議2024年適用版版B版
- 美容院綠色環(huán)保材料采購與2025年度股份合作協(xié)議4篇
- 2025年版餐飲服務消費者免責條款協(xié)議3篇
- 招標師《招標采購項目管理》近年考試真題題庫(含答案解析)
- 微生物組與唾液腺免疫反應-洞察分析
- 2024公共數據授權運營實施方案
- 2024年國家焊工職業(yè)技能理論考試題庫(含答案)
- 《向心力》 教學課件
- 結構力學數值方法:邊界元法(BEM):邊界元法的基本原理與步驟
- 北師大版物理九年級全一冊課件
- 2024年第三師圖木舒克市市場監(jiān)督管理局招錄2人《行政職業(yè)能力測驗》高頻考點、難點(含詳細答案)
- RFJ 006-2021 RFP型人防過濾吸收器制造與驗收規(guī)范(暫行)
- 盆腔炎教學查房課件
- 110kv各類型變壓器的計算單
評論
0/150
提交評論