單片機[CH05]單片機C語言程序設計_第1頁
單片機[CH05]單片機C語言程序設計_第2頁
單片機[CH05]單片機C語言程序設計_第3頁
單片機[CH05]單片機C語言程序設計_第4頁
單片機[CH05]單片機C語言程序設計_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第五章 單片機C語言程序設計概述7/18/20221為什么要使用C語言進行程序開發(fā)C 語言有很好的結(jié)構(gòu)性,便于模塊化,更容易閱讀和維護,程序有很好的可移植性,能夠很方便的從一個工程移植到另一個工程,從而減少開發(fā)時間;用C編寫程序比匯編更符合人們的思考習慣,開發(fā)者可以更專心的考慮解決問題的算法,而不是考慮一些使用匯編語言上的細節(jié)問題,這樣可從總體上減少開發(fā)和調(diào)試的時間。7/18/20222為什么要使用C語言進行程序開發(fā)C語言對使用者盡可能地隱藏了處理器底層的操作,使得代碼可以在不同的目標系統(tǒng)(CPU)之間方便地移植。目前幾乎所有微處理器都有配套的C編譯器;即使如此,匯編語言仍不可替代。首先,掌握

2、匯編語言有利于寫出高質(zhì)量的C語言代碼;其次,在一些時間/速度敏感的操作(如中斷處理)中,使用匯編語言往往是唯一的選擇。7/18/20223第五章 單片機C語言程序設計5.1 C51的數(shù)據(jù)類型與根本運算 7/18/202245.1.1 C51的數(shù)據(jù)類型、變量及存儲模式1、C51的數(shù)據(jù)類型 C51的數(shù)據(jù)結(jié)構(gòu)是以數(shù)據(jù)類型的形式出現(xiàn)的,數(shù)據(jù)類型可分為根本數(shù)據(jù)類型和構(gòu)造(復雜)數(shù)據(jù)類型,構(gòu)造數(shù)據(jù)類型是由根本數(shù)據(jù)類型構(gòu)造而成;C51支持的數(shù)據(jù)類型如下表所示: 7/18/202255.1.1 C51的數(shù)據(jù)類型、變量及存儲模式數(shù)據(jù)類型長度(bit/Byte)取值范圍bit10,1unsigned char8

3、(1B)0255signed char8 (1B)-128127unsigned int16 (2B)065535signed int16 (2B)-3276832767unsigned long32 (4B)04294967295(即232-1)signed long32 (4B)-21474836482147483647float32 (4B)1.175494E-383.402823E+38通用指針24 (3B)可尋址存儲空間范圍065535具體指針8/16 (1/2B)可尋址存儲空間范圍0255 / 0655357/18/202265.1.1 C51的數(shù)據(jù)類型、變量及存儲模式為了更加有利

4、地利用8051的存儲結(jié)構(gòu),C51引入了一種特殊的位數(shù)據(jù)類型(bit)。位數(shù)據(jù)存儲在CPU內(nèi)部的位尋址區(qū)中,可像操作其它變量一樣對其操作,但是位變量不能進行指針操作。7/18/202275.1.1 C51的數(shù)據(jù)類型、變量及存儲模式特殊功能存放器特殊功能存放器用sfr 來定義,而sfr16 用來定義16 位的特殊功能存放器如DPTR;可以通過名字或地址來引用特殊功能存放器。 可位尋址的特殊功能存放器如SCON的位變量定義用關(guān)鍵字sbit 。這些定義是用引入頭文件*.H實現(xiàn)的;Keil為目前大多數(shù)51內(nèi)核的單片機配備了相應的頭文件,這些頭文件包含了該種單片機所有的特殊功能存放器以及控制位的定義,通過

5、包含這些頭文件可以很容易的進行新的擴展。7/18/202285.1.1 C51的數(shù)據(jù)類型、變量及存儲模式SFR在頭文件中的定義sfrSCON=0 x98; / 定義SCONsbitSM0=0 x9F; / 定義SCON 的各位sbitSM1=0 x9E;sbitSM2=0 x9D;sbitREN=0 x9C;sbitTB8=0 x9B;sbitRB8=0X9A;sbitTI=0 x99;sbitRI=0 x98;7/18/202295.1.2 C51運算符、表達式及其規(guī)那么(1) 賦值運算符在C語言中,符號“=被稱為賦值運算符。賦值運算符的作用是將一個數(shù)據(jù)的值賦給一個變量。利用賦值運算符將一個

6、變量與一個表達式連接起來的式子稱為賦值表達式,在賦值表達式的后面加一個分號“;便構(gòu)成了賦值語句。一個賦值語句的格式如下:變量 = 表達式;例如:x = 9;7/18/2022105.1.2 C51運算符、表達式及其規(guī)那么(2) 算術(shù)運算符根本的算術(shù)運算符有五種:+加或取正值運算符-減或取負值運算符*乘運算符/除運算符%取余運算符運算優(yōu)先級:先乘除、取模,后加減,括號最優(yōu)先運算時類型轉(zhuǎn)換優(yōu)先級char int long double float7/18/2022115.1.2 C51運算符、表達式及其規(guī)那么(3)自增量和自減量運算符 根本的運算符有兩種:+增量運算符-減量運算符作用:對運算對象作

7、加l和減1運算特點:位置相關(guān),+i與i+加1操作執(zhí)行順序不同+/-只能用于變量,不能用于常數(shù)或表達式7/18/2022125.1.2 C51運算符、表達式及其規(guī)那么(4)關(guān)系運算符 根本的關(guān)系運算符有六種:大于=大于等于=小于等于=等于!=不等于格式:表達式1 關(guān)系運算符 表達式2特點:用來判別某個條件是否滿足,當所指定的條件滿足時結(jié)果為1,不滿足時結(jié)果為0。 優(yōu)先級相同(高)優(yōu)先級相同(低)7/18/2022135.1.2 C51運算符、表達式及其規(guī)那么(5)邏輯運算符 根本的邏輯運算符有三種:|邏輯或&邏輯與!邏輯非使用邏輯運算符求某個條件表達式的邏輯值,就是邏輯表達式,例如:x & y;

8、/ x,y都為真時返回真a | b;/ a,b任一為真時返回真!z;/ 對z取非7/18/2022145.1.2 C51運算符、表達式及其規(guī)那么(6)位運算符 根本的位運算符有六種:按位取反右移&按位與按位異或|按位或按位對變量進行運算,但并不改變參與運算的變量的值。位運算的一般形式如下:x 2;/ 將變量x中的各位左移2位7/18/2022155.1.2 C51運算符、表達式及其規(guī)那么(7)復合賦值運算符 在賦值運算符“=的前面加上其它運算符,就構(gòu)成了復合賦值運算符。 可以和“=構(gòu)成復合賦值運算符的運算符包括:+、-、*、/、%、&、|、 例如:x += 2;/ 將變量x加2后存回x中等價于

9、:x = x+2;7/18/2022165.1.2 C51運算符、表達式及其規(guī)那么(8)條件運算符 “?:是C語言中唯一的一個三目運算符,將三個表達式連接起來構(gòu)成一個條件表達式,格式為:邏輯表達式 ? 表達式1 : 表達式2當邏輯表達式為真時,返回表達式1的值,否那么返回表達式2的值。例如:max = ab ? a : b;/ 取a和b中的大值等價于:if(ab) max = a;else max = b;7/18/2022175.1.2 C51運算符、表達式及其規(guī)那么(9)指針和地址運算符 對于指針和地址,C語言提供了兩種運算符:*指針,取指向的內(nèi)容&地址,取變量的地址取內(nèi)容和取地址運算的一

10、般形式分別為: 變量 = *指針變量;指針變量 = &目標變量;7/18/2022185.1.2 C51運算符、表達式及其規(guī)那么(9)指針和地址運算符 例如:int i,j,*ptr;i = 100;/ 將100賦值給iptr = &i;/ 此時ptr指向變量i,即ptr中/ 存放的是變量i的存儲地址j = *ptr; / 將ptr指向的存儲地址單元中的/ 值賦給j,即執(zhí)行后j也為1007/18/2022195.1.2 C51運算符、表達式及其規(guī)那么(10) 類型轉(zhuǎn)換C語言中可以進行兩種類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換強制類型轉(zhuǎn)換當程序中兩種不同類型的變量互相賦值或進行運算時,編譯器會自動進行隱式類型轉(zhuǎn)

11、換,將低優(yōu)先級的數(shù)據(jù)類型轉(zhuǎn)換為高優(yōu)先級的數(shù)據(jù)。轉(zhuǎn)換優(yōu)先級從低到高為:char int long double float7/18/2022205.1.2 C51運算符、表達式及其規(guī)那么(10) 強制類型轉(zhuǎn)換C語言中還可以用括號進行強制的類型轉(zhuǎn)換,方法為:(類型名) 變量名;或:(類型名) 表達式;例如:int var1;unsigned char var2;var1 = (int) var2;/ var2轉(zhuǎn)換為整型var2 = (unsigned char) var1;/ var1轉(zhuǎn)換為字符型7/18/2022215.1.2 C51運算符、表達式及其規(guī)那么(11) sizeof運算符C語言中提

12、供了一種用于求取數(shù)據(jù)類型、變量以及表達式在存儲器中占用的字節(jié)數(shù)的運算符:sizeof,該運算符的一般使用形式為: sizeof(表達式);或sizeof(數(shù)據(jù)類型);例如:sizeof(char);sizeof(int);注意sizeof是一個表達式而不是一個函數(shù),這個表達式的值在編譯時就已經(jīng)由編譯器計算出來了,而不是在程序執(zhí)行的過程中計算的。 7/18/2022225.1.3 C51的存儲模式C51編譯器完全支持MCS-51型單片機的存儲結(jié)構(gòu)。該編譯器引入了存儲模式關(guān)鍵字,通過將變量、常量定義成不同的存儲模式(類型)的方法,將它們定位在不同的存儲空間中。在C51中對變量進行定義的格式如下:存

13、儲種類 數(shù)據(jù)類型 存儲器類型 變量名表;存儲種類和存儲器類型是可選項。變量的存儲種類有自動(auto)、外部(extern)、靜態(tài)(static)和存放器(register)共四種。如果定義變量時省略了存儲種類,那么該變量缺省為自動(auto)變量。 7/18/2022235.1.3 C51的存儲模式C51還允許程序指定變量的存儲器類型。C51編譯器支持的存儲器類型及存儲空間以及訪問方式為:存儲區(qū)變量存儲位置及訪問方式data變量存儲于內(nèi)部RAM 的低128字節(jié),可在一個機器周期內(nèi)直接尋址bdata變量存儲于內(nèi)部RAM 20H2FH共16個字節(jié)的可位尋址區(qū)idata變量存儲于內(nèi)部RAM的高12

14、8個字節(jié),采用間接尋址方式訪問pdata變量存儲于外部RAM區(qū)的低256字節(jié),使用MOVX Ri指令通過P0 口輸出8位地址對其進行間接尋址,需要兩個機器周期xdata變量存放于整個外部RAM區(qū),使用DPTR間接尋址的方式訪問,可訪問空間范圍為64KBcode變量存放于程序存儲器區(qū),使用DPTR或PC尋址,尋址范圍64KB7/18/2022245.1.3 C51的存儲模式1、data存儲模式由于編譯器會把聲明為data的變量存放在單片機內(nèi)部RAM的低128字節(jié),并通過直接尋址的方式訪問,因此對data區(qū)的尋址是最快的,所以應該把使用頻率高的變量放在data區(qū)。但要注意的是聲明為data類的存儲

15、區(qū)除了包含程序變量外,還包含了堆棧和存放器組。使用時要加以注意。data存儲模式的聲明如下:7/18/2022255.1.3 C51的存儲模式1、data存儲模式data存儲模式的聲明如下:unsigned char data system_status=0;unsigned int data unit_id2;data char input_string16;float data output_value;mytype data new_var;注意:如果某變量聲明未指定類型,那么編譯器會將其放在當前存儲模式的缺省數(shù)據(jù)區(qū)。7/18/2022265.1.3 C51的存儲模式1、data存儲模式

16、只要不超過內(nèi)部data區(qū)的范圍,系統(tǒng)變量和用戶變量均可存放在其中。使用時要考慮到C51使用存放器組傳遞函數(shù)的參數(shù)(因此data區(qū)至少被占用8字節(jié)),此外還要留出足夠的堆??臻g(大小和中斷源數(shù)、函數(shù)調(diào)用嵌套層數(shù)相關(guān),編譯器會自動處理,用戶根本不用考慮此問題。這一點也是高級語言比匯編更方便的原因之一)。7/18/2022275.1.3 C51的存儲模式2、bdata存儲模式定義為bdata存儲類型的變量,可以進行位尋址,可聲明位變量。這對于一些需要單獨操作字節(jié)中某些位的應用場合非常適用;但是要注意,bdata存儲區(qū)只能存儲字符型及整型變量,編譯器不允許在bdata存儲區(qū)中定義float、doubl

17、e類型的變量。7/18/2022285.1.3 C51的存儲模式3、idata存儲模式idata存儲區(qū)對應MCS-52系列單片機內(nèi)部RAM的高128字節(jié)的存儲空間,也可存放使用比較頻繁的變量。這些變量使用MOV R0和MOV R1存放器間接尋址方式進行尋址。和外部存儲器尋址比較,它的指令執(zhí)行周期和代碼長度都比較短。例如:unsigned char idata system_status=0;unsigned int idata unit_id2;idata char input_string16;idata float output_value;7/18/2022295.1.3 C51的存儲模

18、式4、pdata和xdata存儲模式pdata存儲區(qū)對應外部RAM最低256字節(jié)的存儲空間,通過MOVX R0/R1間址方式尋址。xdata區(qū)那么對應全部外部RAM的64K尋址空間,通過MOVX DPTR方式尋址。由于pdata區(qū)的地址為8位而xdata區(qū)為16位,因此pdata區(qū)的尋址比xdata區(qū)的尋址快。unsigned char xdata system_status=0;unsigned int pdata unit_id2;xdata char input_string16;pdata float output_value;7/18/2022305.1.3 C51的存儲模式4、pd

19、ata和xdata存儲模式外部RAM地址除了訪問物理存儲器的地址外,還包含I/O器件的譯碼選通地址。對外部器件尋址可通過指針或C51提供的宏來完成,可讀性更好。宏定義看上去像char或int類型的數(shù)組:inp_byte = XBYTE0 x8500;/ 從XRAM地址8500H讀一個字節(jié)inp_word = XWORD0 x4000;/ 從XRAM地址4000H讀兩個字節(jié)XBYTE0 x7500=out_val;/ 寫一個字節(jié)到XRAM的7500H可對外部RAM中除bdata存儲區(qū)之外的其它數(shù)據(jù)段采用以上方法尋址。使用絕對地址訪問的宏需要包含頭文件 absacc.h7/18/2022315.1

20、.3 C51的存儲模式5、code存儲模式MCS-51的代碼區(qū)為只讀存儲器,不可重寫。一般代碼區(qū)中除了程序代碼外,還可存放數(shù)據(jù)表。數(shù)據(jù)表在源程序中定義,在編譯過程中初始化。unsigned int code unit_id = 1234;unsigned char code Table = 0 x00, 0 x01, 0 x02, 0 x03, 0 x04, 0 x05;7/18/2022325.1.4 C51的指針指針的本質(zhì)是一個與地址相關(guān)的復合類型,它的值是數(shù)據(jù)存放的位置(地址)。C51提供一個3字節(jié)的通用存儲器指針,通用指針的第一個字節(jié)說明指針所指向的變量的存儲空間,另外兩個字節(jié)存儲16

21、位偏移量。對明確聲明為data、idata和pdata類型的指針只需要8位偏移量。7/18/2022335.1.4 C51的指針Keil允許使用者規(guī)定指針指向的存儲區(qū)。這種指針叫具體指針。使用具體指針的好處是節(jié)省了存儲空間,編譯器不用根據(jù)指針類型選擇存儲空間、確定尋址方式,這樣就使代碼更加簡短。char *str1;/ 未指明存儲空間,通用指針char data *str2;/ 指明存儲空間,具體指針由于具體指針操作比通用指針的操作快得多,因此在一般情況下,不推薦使用通用指針。7/18/2022345.1.4 C51的指針使用指針時必須注意1、指針不能越界;這種錯誤編譯器無法發(fā)現(xiàn),且調(diào)試中不易

22、發(fā)現(xiàn);2、不同類型的指針之間如果需要賦值,必須經(jīng)過顯式強制類型轉(zhuǎn)換。指針類型存儲空間通用指針3字節(jié)xdata指針2字節(jié)code指針2字節(jié)pdata指針1字節(jié)data指針1字節(jié)idata指針1字節(jié)7/18/2022355.1.5 C51的中斷效勞程序在C51中可以用C來聲明中斷和編寫中斷效勞程序。中斷過程通過使用interrupt關(guān)鍵字和中斷號(031)來實現(xiàn)。編譯器根據(jù)中斷號計算中斷效勞程序的入口地址。中斷號和MCS-51中斷源之間的關(guān)系如下:中斷號中斷源0外部中斷01定時器/計數(shù)器0溢出中斷2外部中斷13定時器/計數(shù)器1溢出中斷4串行口中斷5定時器/計數(shù)器2溢出中斷7/18/2022365.

23、1.5 C51的中斷效勞程序編譯器在生成中斷效勞程序時,會自動在入口處保護所有將在ISR中使用的存放器、存儲單元(壓入堆棧),并在退出ISR之前恢復現(xiàn)場。可以通過using關(guān)鍵字指定某ISR使用的具體的存放器組:void Int0Isr(void) interrupt 0 using 3 7/18/2022375.1.5 C51的中斷效勞程序此時在ISR入口處將不再產(chǎn)生將當前存放器組壓入堆棧的代碼,這樣有利于快速響應中斷。但因為在C中所有函數(shù)參數(shù)傳遞、指針引用等都要用到存放器間接尋址的方式,因此,這種方法帶來的副作用是:所有ISR中調(diào)用的函數(shù)、使用的變量都必須基于同一個存放器組,否那么將出錯。

24、7/18/2022385.1.6 高質(zhì)量的C51編程1、采用短變量一個提高代碼效率的最根本的方式就是減小變量的字長,提高速度。例如,使用傳統(tǒng)C編程時我們都習慣于對循環(huán)控制變量使用int類型,如果循環(huán)次數(shù)在255次以下,完全可以采用unsigned char型變量作為循環(huán)控制變量。編程者應該根據(jù)變量值可能的取值范圍選擇適宜的變量類型(字長)。7/18/2022395.1.6 高質(zhì)量的C51編程2、盡量使用無符號類型變量由于MCS-51并不支持符號運算,符號運算要通過庫函數(shù)等方式實現(xiàn),這會引起程序性能的下降。編程者應根據(jù)應用的具體情況,盡量不使用帶符號的變量。7/18/2022405.1.6 高質(zhì)

25、量的C51編程3、防止使用浮點數(shù)及浮點數(shù)指針在8位字長的單片機系統(tǒng)上使用32位浮點數(shù)會引起程序體積的增大和程序效率的極大下降。在實際使用中,可以通過提高數(shù)值數(shù)量級和使用整型運算來防止使用浮點數(shù)/指針運算。7/18/2022415.1.6 高質(zhì)量的C51編程4、盡可能多使用位變量對于程序中使用的只有兩種取值的標志位,應盡可能使用位變量而不是char。這將提高操作效率,節(jié)省內(nèi)存。7/18/2022425.1.6 高質(zhì)量的C51編程5、用局部變量代替全局變量把變量定義成局部變量比全局變量更有效率。編譯器可通過覆蓋處理使內(nèi)存的使用效率更高,同時還可以防止多個程序調(diào)用公共變量時引起的同步問題。7/18/

26、2022435.1.6 高質(zhì)量的C51編程6、盡量將變量分配在內(nèi)部存儲區(qū)這樣可以提高程序運行的速度、減小代碼占用的空間。在保證足夠的堆??臻g的情況下,建議按以下順序定義變量:data idata pdata xdata對應尋址方式:data:直接尋址。如 MOV A,30Hidata:R07間接尋址。如 MOV A,R7pdata:外部RAM R0,1間址。如 MOVX A,R0 xdata:外部RAM DPTR間址。MOVX A,DPTR7/18/2022445.1.6 高質(zhì)量的C51編程7、使用特定指針在定義指針時應明確指定其所指向的存儲類型,如data、xdata等,這樣編譯器會根據(jù)指針的存儲空間自動生成適宜的指針代碼,這樣速度更快,代碼更緊湊。通用指針需占用3字節(jié)代碼空間,而xdata指針以及code指針為2字節(jié),data、idata、pdata指針只有1字節(jié)。7/18/2022455.1.6 高質(zhì)量的C51編程8、使用內(nèi)聯(lián)函數(shù)對于一些簡單的操作如變量循環(huán)位移,編譯器提供了一些內(nèi)聯(lián)函數(shù)供用戶調(diào)用。多數(shù)內(nèi)聯(lián)函數(shù)直接對應著匯編指令,因此可較大地提高

溫馨提示

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

最新文檔

評論

0/150

提交評論