單片機C語言程序設(shè)計課件_第1頁
單片機C語言程序設(shè)計課件_第2頁
單片機C語言程序設(shè)計課件_第3頁
單片機C語言程序設(shè)計課件_第4頁
單片機C語言程序設(shè)計課件_第5頁
已閱讀5頁,還剩237頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第四章單片機C語言程序設(shè)計4.1C語言與MCS-51單片機4.1.1C語言的特點及程序結(jié)構(gòu)一.C語言的特點1.語言簡潔、緊湊,使用方便、靈活。2.運算符豐富。3.?dāng)?shù)據(jù)結(jié)構(gòu)豐富。具有現(xiàn)代化語言的各種數(shù)據(jù)結(jié)構(gòu)。4.可進行結(jié)構(gòu)化程序設(shè)計。5.可以直接對計算機硬件進行操作。6.生成的目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高。7.可移植性好。第四章單片機C語言程序設(shè)計4.1C語言與MCS-51單1二.C語言的程序結(jié)構(gòu)C語言程序采用函數(shù)結(jié)構(gòu),每個C語言程序由一個或多個函數(shù)組成,在這些函數(shù)中至少應(yīng)包含一個主函數(shù)main(),也可以包含一個main()函數(shù)和若干個其它的功能函數(shù)。不管main()函數(shù)放于何處,程序總是從main()函數(shù)開始執(zhí)行,執(zhí)行到main()函數(shù)結(jié)束則結(jié)束。在main()函數(shù)中調(diào)用其它函數(shù),其它函數(shù)也可以相互調(diào)用,但main()函數(shù)只能調(diào)用其它的功能函數(shù),而不能被其它的函數(shù)所調(diào)用。功能函數(shù)可以是C語言編譯器提供的庫函數(shù),也可以是由用戶定義的自定義函數(shù)。在編制C程序時,程序的開始部分一般是預(yù)處理命令、函數(shù)說明和變量定義等。

二.C語言的程序結(jié)構(gòu)C語言程序采用函數(shù)結(jié)構(gòu),每24.1.2C語言與MCS-51單片機

用C語言編寫MCS-51單片機程序與用匯編語言編寫MCS–51單片機程序不一樣。用匯編語言編寫MCS–51單片機程序必須要考慮其存儲器結(jié)構(gòu),尤其必須考慮其片內(nèi)數(shù)據(jù)存儲器與特殊功能寄存器的使用以及按實際地址處理端口數(shù)據(jù)。用C語言編寫的MCS–51單片機應(yīng)用程序,則不用像匯編語言那樣須具體組織、分配存儲器資源和處理端口數(shù)據(jù),但在C語言編程中,對數(shù)據(jù)類型與變量的定義,必須要與單片機的存儲結(jié)構(gòu)相關(guān)聯(lián),否則編譯器不能正確地映射定位。

4.1.2C語言與MCS-51單片機用C語言編寫3

C語言編寫單片機應(yīng)用程序時,需根據(jù)單片機存儲結(jié)構(gòu)及內(nèi)部資源定義相應(yīng)的數(shù)據(jù)類型和變量,而標(biāo)準(zhǔn)的C語言程序不需要考慮這些問題;C51包含的數(shù)據(jù)類型、變量存儲模式、輸入輸出處理、函數(shù)等方面與標(biāo)準(zhǔn)的C語言有一定的區(qū)別。其它的語法規(guī)則、程序結(jié)構(gòu)及程序設(shè)計方法等與標(biāo)準(zhǔn)的C語言程序設(shè)計相同。

用C語言編寫單片機應(yīng)用程序與標(biāo)準(zhǔn)的C語言程序也有相應(yīng)的區(qū)別:C語言編寫單片機應(yīng)用程序時,需根據(jù)單片機4

現(xiàn)在支持MCS-51系列單片機的C語言編譯器有很多種,如AmericanAutomation、Avocet、BSO/TASKING、DUNFIELDSHAREWARE、KEIL/Franklin等。各種編譯器的基本情況相同,但具體處理時有一定的區(qū)別,其中KEIL/Franklin以它的代碼緊湊和使用方便等特點優(yōu)于其它編譯器,現(xiàn)在使用特別廣泛。

本章主要以KEIL編譯器介紹MCS-51單片機C語言程序設(shè)計?,F(xiàn)在支持MCS-51系列單片機的C語言編譯器54.1.3C51程序結(jié)構(gòu)C51的語法規(guī)定、程序結(jié)構(gòu)及程序設(shè)計方法都與標(biāo)準(zhǔn)的C語言程序設(shè)計相同,但C51程序與標(biāo)準(zhǔn)的C程序在以下幾個方面不一樣:(1)C51中定義的庫函數(shù)和標(biāo)準(zhǔn)C語言定義的庫函數(shù)不同。標(biāo)準(zhǔn)的C語言定義的庫函數(shù)是按通用微型計算機來定義的,而C51中的庫函數(shù)是按MCS-51單片機相應(yīng)情況來定義的;(2)C51中的數(shù)據(jù)類型與標(biāo)準(zhǔn)C的數(shù)據(jù)類型也有一定的區(qū)別,在C51中還增加了幾種針對MCS-51單片機特有的數(shù)據(jù)類型;4.1.3C51程序結(jié)構(gòu)C51的語法規(guī)定、程序結(jié)6(3)C51變量的存儲模式與標(biāo)準(zhǔn)C中變量的存儲模式不一樣,C51中變量的存儲模式是與MCS-51單片機的存儲器緊密相關(guān);(4)C51與標(biāo)準(zhǔn)C的輸入輸出處理不一樣,C51中的輸入輸出是通過MCS-51串行口來完成的,輸入輸出指令執(zhí)行前必須要對串行口進行初始化;(5)C51與標(biāo)準(zhǔn)C在函數(shù)使用方面也有一定的區(qū)別,C51中有專門的中斷函數(shù)。(3)C51變量的存儲模式與標(biāo)準(zhǔn)C中變量的存儲模式不一樣,C74.2C51的數(shù)據(jù)類型C51的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和組合數(shù)據(jù)類型,情況與標(biāo)準(zhǔn)C中的數(shù)據(jù)類型基本相同,但其中char型與short型相同,float型與double型相同,另外,C51中還有專門針對于MCS-51單片機的特殊功能寄存器型和位類型。4.2C51的數(shù)據(jù)類型C51的數(shù)據(jù)類型分為8一.字符型char有signedchar和unsignedchar之分,默認(rèn)為signedchar。它們的長度均為一個字節(jié),用于存放一個單字節(jié)的數(shù)據(jù)。

對于signedchar,它用于定義帶符號字節(jié)數(shù)據(jù),其字節(jié)的最高位為符號位,“0”表示正數(shù),“1”表示負(fù)數(shù),補碼表示,所能表示的數(shù)值范圍是-128~+127;

對于unsignedchar,它用于定義無符號字節(jié)數(shù)據(jù)或字符,可以存放一個字節(jié)的無符號數(shù),其取值范圍為0~255。unsignedchar可以用來存放無符號數(shù),也可以存放西文字符,一個西文字符占一個字節(jié),在計算機內(nèi)部用ASCII碼存放。

一.字符型char9二.int整型分singedint和unsignedint。默認(rèn)為signedint。它們的長度均為兩個字節(jié),用于存放一個雙字節(jié)數(shù)據(jù)。對于signedint,用于存放兩字節(jié)帶符號數(shù),補碼表示,數(shù)的范疇為-32768~+32767。對于unsignedint,用于存放兩字節(jié)無符號數(shù),數(shù)的范圍為0~65535。三.long長整型分singedlong和unsignedlong。默認(rèn)為signedlong。它們的長度均為四個字節(jié),用于存放一個四字節(jié)數(shù)據(jù)。對于signedlong,用于存放四字節(jié)帶符號數(shù),補碼表示,數(shù)的范疇為-2147483648~+2147483647。對于unsignedlong,用于存放四字節(jié)無符號數(shù),數(shù)的范圍為0~4294967295。二.int整型三.long長整型10四.float浮點型float型數(shù)據(jù)的長度為四個字節(jié),格式符合IEEE-754標(biāo)準(zhǔn)的單精度浮點型數(shù)據(jù),包含指數(shù)和尾數(shù)兩部分,最高位為符號位,“1”表示負(fù)數(shù),“0”表示正數(shù),其次的8位為階碼,最后的23位為尾數(shù)的有效數(shù)位,由于尾數(shù)的整數(shù)部分隱含為“1”,所以尾數(shù)的精度為24位。五.*指針型指針型本身就是一個變量,在這個變量中存放的指向另一個數(shù)據(jù)的地址。這個指針變量要占用一定的內(nèi)存單元,對不同的處理器其長度不一樣,在C51中它的長度一般為1~3個字節(jié)。四.float浮點型11六.特殊功能寄存器型這是C51擴充的數(shù)據(jù)類型,用于訪問MCS-51單片機中的特殊功能寄存器數(shù)據(jù),它分sfr和sfr16兩種類型。其中:sfr為字節(jié)型特殊功能寄存器類型,占一個內(nèi)存單元,利用它可以訪問MCS-51內(nèi)部的所有特殊功能寄存器;sfr16為雙字節(jié)型特殊功能寄存器類型,占用兩個字節(jié)單元,利用它可以訪問MCS-51內(nèi)部的所有兩個字節(jié)的特殊功能寄存器。

在C51中對特殊功能寄存器的訪問必須先用sfr或sfr16進行聲明。六.特殊功能寄存器型12七.位類型這也是C51中擴充的數(shù)據(jù)類型,用于訪問MCS-51單片機中的可尋址的位單元。在C51中,支持兩種位類型:bit型和sbit型。它們在內(nèi)存中都只占一個二進制位,其值可以是“1”或“0”。其中:用bit定義的位變量在C51編譯器編譯時,在不同的時候位地址是可以變化的,而用sbit定義的位變量必須與MCS-51單片機的一個可以尋址位單元或可位尋址的字節(jié)單元中的某一位聯(lián)系在一起,在C51編譯器編譯時,其對應(yīng)的位地址是不可變化的。七.位類型13基本數(shù)據(jù)類型長度取值范圍unsignedchar1字節(jié)0~255signedchar1字節(jié)-128~+127unsignedint2字節(jié)0~65535signedint2字節(jié)-32768~+32767unsignedlong4字節(jié)0~4294967295signedlong4字節(jié)-2147483648~+2147483647float4字節(jié)1.175494E-38~3.402823E+38bit1位0或1sbit1位0或1sfr1字節(jié)0~255sfr162字節(jié)0~65535KEILC51編譯器能夠識別的基本數(shù)據(jù)類型:基本數(shù)據(jù)類型長度取值范圍unsignedchar1字節(jié)0~14在C51語言程序中,有可能會出現(xiàn)在運算中數(shù)據(jù)類型不一致的情況。C51允許任何標(biāo)準(zhǔn)數(shù)據(jù)類型的隱式轉(zhuǎn)換,隱式轉(zhuǎn)換的優(yōu)先級順序如下:

bitcharintlongfloatsignedunsigned也就是說,當(dāng)char型與int型進行運算時,先自動對char型擴展為int型,然后與int型進行運算,運算結(jié)果為int型。C51除了支持隱式類型轉(zhuǎn)換外,還可以通過強制類型轉(zhuǎn)換符“()”對數(shù)據(jù)類型進行人為的強制轉(zhuǎn)換。C5l編譯器除了能支持以上這些基本數(shù)據(jù)類型之外,還能支持一些復(fù)雜的組合型數(shù)據(jù)類型,如數(shù)組類型、指針類型、結(jié)構(gòu)類型、聯(lián)合類型等這些復(fù)雜的數(shù)據(jù)類型,在后面將相繼介紹。在C51語言程序中,有可能會出現(xiàn)在運算中數(shù)據(jù)類型不154.3.1常量常量是指在程序執(zhí)行過程中其值不能改變的量。在C51中支持整型常量、浮點型常量、字符型常量和字符串型常量。一.整型常量整型常量也就是整型常數(shù),根據(jù)其值范圍在計算機中分配不同的字節(jié)數(shù)來存放。在C51中它可以表示成以下幾種形式:十進制整數(shù)。如234、-56、0等。十六進制整數(shù)。以0x開頭表示,如0x12表示十六進制數(shù)12H。長整數(shù)。在C51中當(dāng)一個整數(shù)的值達到長整型的范圍,則該數(shù)按長整型存放,在存儲器中占四個字節(jié),另外,如一個整數(shù)后面加一個字母L,這個數(shù)在存儲器中也按長整型存放。如123L在存儲器中占四個字節(jié)。4.3C51的運算量4.3.1常量一.整型常量4.3C51的運算量16二.浮點型常量浮點型常量也就是實型常數(shù)。有十進制表示形式和指數(shù)表示形式。十進制表示形式又稱定點表示形式,由數(shù)字和小數(shù)點組成。如0.123、34.645等都是十進制數(shù)表示形式的浮點型常量。指數(shù)表示形式為:[]數(shù)字[.數(shù)字]e[]數(shù)字例如:123.456e-3、-3.123e2等都是指數(shù)形式的浮點型常量。二.浮點型常量17三.字符型常量字符型常量是用單引號引起的字符,如‘a(chǎn)’、‘1’、‘F’等。可以是可顯示的ASCII字符,也可以是不可顯示的控制字符。對不可顯示的控制字符須在前面加上反斜杠“\”組成轉(zhuǎn)義字符。利用它可以完成一些特殊功能和輸出時的格式控制。常用的轉(zhuǎn)義字符如下表所示。

三.字符型常量18轉(zhuǎn)義字符含義ASCII碼(十六進制數(shù))\o空字符(null)00H\n換行符(LF)0AH\r回車符(CR)0DH\t水平制表符(HT)09H\b退格符(BS)08H\f換頁符(FF)0CH\‘單引號27H\”雙引號22H\\反斜杠5CH轉(zhuǎn)義字符含義ASCII碼(十六進制數(shù))\o空字符(nu19四.字符串型常量字符串型常量由雙引號“”括起的字符組成。如“D”、“1234”、“ABCD”等。注意字符串常量與字符常量是不一樣,一個字符常量在計算機內(nèi)只用一個字節(jié)存放,而一個字符串常量在內(nèi)存中存放時不僅雙引號內(nèi)的字符一個占一個字節(jié),而且系統(tǒng)會自動的在后面加一個轉(zhuǎn)義字符“\o”作為字符串結(jié)束符。因此不要將字符常量和字符串常量混淆,如字符常量‘A’和字符串常量“A”是不一樣的。四.字符串型常量204.3.2變量變量是在程序運行過程中其值可以改變的量。一個變量由兩部分組成:變量名和變量值。在C51中,變量在使用前必須對變量進行定義,指出變量的數(shù)據(jù)類型和存儲模式。以便編譯系統(tǒng)為它分配相應(yīng)的存儲單元。定義的格式如下:[存儲種類]數(shù)據(jù)類型說明符[存儲器類型]變量名1[=初值],變量名2[初值]…;4.3.2變量21一.?dāng)?shù)據(jù)類型說明符在定義變量時,必須通過數(shù)據(jù)類型說明符指明變量的數(shù)據(jù)類型,指明變量在存儲器中占用的字節(jié)數(shù)??梢允腔緮?shù)據(jù)類型說明符,也可以是組合數(shù)據(jù)類型說明符,還可以是用typedef定義的類型別名。在C51中,為了增加程序的可讀性,允許用戶為系統(tǒng)固有的數(shù)據(jù)類型說明符用typedef起別名,格式如下:

typedefc51固有的數(shù)據(jù)類型說明符別名;定義別名后,就可以用別名代替數(shù)據(jù)類型說明符對變量進行定義。別名可以用大寫,也可以用小寫,為了區(qū)別一般用大寫字母表示。【例】typedef的使用。typedefunsignedintWORD;typedefunsignedcharBYTE;BYTEa1=0x12;WORDa2=0x1234;一.?dāng)?shù)據(jù)類型說明符【例】typedef的使用。22二.變量名變量名是C51區(qū)分不同變量,為不同變量取的名稱。在C51中規(guī)定變量名可以由字母、數(shù)字和下劃線三種字符組成,且第一個字母必須為字母或下劃線。變量名有兩種:普通變量名和指針變量名。它們的區(qū)別是指針變量名前面要帶“*”號。二.變量名23三.存儲種類存儲種類是指變量在程序執(zhí)行過程中的作用范圍。C51變量的存儲種類有四種,分別是自動(auto)、外部(extern)、靜態(tài)(static)和寄存器(register)。1.a(chǎn)uto:

使用auto定義的變量稱為自動變量,其作用范圍在定義它的函數(shù)體或復(fù)合語句內(nèi)部,當(dāng)定義它的函數(shù)體或復(fù)合語句執(zhí)行時,C51才為該變量分配內(nèi)存空間,結(jié)束時占用的內(nèi)存空間釋放。自動變量一般分配在內(nèi)存的堆棧空間中。定義變量時,如果省略存儲種類,則該變量默認(rèn)為自動(auto)變量。三.存儲種類242.extern:

使用extern定義的變量稱為外部變量。在一個函數(shù)體內(nèi),要使用一個已在該函數(shù)體外或別的程序中定義過的外部變量時,該變量在該函數(shù)體內(nèi)要用extern說明。外部變量被定義后分配固定的內(nèi)存空間,在程序整個執(zhí)行時間內(nèi)都有效,直到程序結(jié)束才釋放。3.static:

使用static定義的變量稱為靜態(tài)變量。它又分為內(nèi)部靜態(tài)變量和外部靜態(tài)變量。在函數(shù)體內(nèi)部定義的靜態(tài)變量為內(nèi)部靜態(tài)變量,它在對應(yīng)的函數(shù)體內(nèi)有效,一直存在,但在函數(shù)體外不可見,這樣不僅使變量在定義它的函數(shù)體外被保護,還可以實現(xiàn)當(dāng)離開函數(shù)時值不被改變。外部靜態(tài)變量上在函數(shù)外部定義的靜態(tài)變量。它在程序中一直存在,但在定義的范圍之外是不可見的。如在多文件或多模塊處理中,外部靜態(tài)變量只在文件內(nèi)部或模塊內(nèi)部有效。2.extern:254.register:

使用register定義的變量稱為寄存器變量。它定義的變量存放在CPU內(nèi)部的寄存器中,處理速度快,但數(shù)目少。C51編譯器編譯時能自動識別程序中使用頻率最高的變量,并自動將其作為寄存器變量,用戶可以無需專門聲明。4.register:26四.存儲器類型存儲器類型是用于指明變量所處的單片機的存儲器區(qū)域情況。存儲器類型與存儲種類完全不同。C51編譯器能識別的存儲器類型有以下幾種,見表所示。存儲器類型描述data直接尋址的片內(nèi)RAM低128B,訪問速度快bdata片內(nèi)RAM的可位尋址區(qū)(20H~2FH),允許字節(jié)和位混合訪問idata間接尋址訪問的片內(nèi)RAM,允許訪問全部片內(nèi)RAMpdata用Ri間接訪問的片外RAM的低256Bxdata用DPTR間接訪問的片外RAM,允許訪問全部64k片外RAMcode程序存儲器ROM64k空間定義變量時也可以省“存儲器類型”,省時C51編譯器將按編譯模式默認(rèn)存儲器類型,具體編譯模式的情況在后面介紹。四.存儲器類型存儲器類型描述data直接尋址的片內(nèi)RA27【例】變量定義存儲種類和存儲器類型相關(guān)情況。

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

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

autounsignedlongdatavar3;/*在片內(nèi)RAM128B定義用直接尋址方式訪問的自動無符號長整型變量var3*/

externfloatxdatavar4;/*在片外RAM64KB空間定義用間接尋址方式訪問的外部實型變量var4*/

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

unsigncharbdatavar6;/*在片內(nèi)RAM位尋址區(qū)20H~2FH單元定義可字節(jié)處理和位處理的無符號字符型變量var6*/【例】變量定義存儲種類和存儲器類型相關(guān)情況。28五.特殊功能寄存器變量MCS-51系列單片機片內(nèi)有許多特殊功能寄存器,通過這些特殊功能寄存器可以控制MCS-51系列單片機的定時器、計數(shù)器、串口、I/O及其它功能部件,每一個特殊功能寄存器在片內(nèi)RAM中都對應(yīng)于一個字節(jié)單元或兩個字節(jié)單元。在C51中,允許用戶對這些特殊功能寄存器進行訪問,訪問時須通過sfr或sfr16類型說明符進行定義,定義時須指明它們所對應(yīng)的片內(nèi)RAM單元的地址。格式如下:sfr或sfr16特殊功能寄存器名=地址;sfr用于對MCS-51單片機中單字節(jié)的特殊功能寄存器進行定義,sfr16用于對雙字節(jié)特殊功能寄存器進行定義。特殊功能寄存器名一般用大寫字母表示。地址一般用直接地址形式,具體特殊功能寄存器地址見前面內(nèi)容?!纠?-3】特殊功能寄存器的定義。sfrPSW=0xd0;sfrSCON=0x98;sfrTMOD=0x89;sfrP1=0x90;sfr16DPTR=0x82;sfr16T1=0X8A;五.特殊功能寄存器變量【例4-3】特殊功能寄存器的定義。29六.位變量在C51中,允許用戶通過位類型符定義位變量。位類型符有兩個:bit和sbit??梢远x兩種位變量。bit位類型符用于定義一般的可位處理位變量。它的格式如下:bit位變量名;在格式中可以加上各種修飾,但注意存儲器類型只能是bdata、data、idata。只能是片內(nèi)RAM的可位尋址區(qū),嚴(yán)格來說只能是bdata?!纠縝it型變量的定義。 bitdataa1;/*正確*/ bitbdataa2;/*正確*/ bitpdataa3;/*錯誤*/ bitxdataa4;/*錯誤*/六.位變量30sbit位類型符用于定義在可位尋址字節(jié)或特殊功能寄存器中的位,定義時須指明其位地址,可以是位直接地址,可以是可位尋址變量帶位號,也可以是特殊功能寄存器名帶位號。格式如下:

sbit位變量名=位地址;如位地址為位直接地址,其取值范圍為0x00~0xff;如位地址是可位尋址變量帶位號或特殊功能寄存器名帶位號,則在它前面須對可位尋址變量或特殊功能寄存器進行定義。字節(jié)地址與位號之間、特殊功能寄存器與位號之間一般用“^”作間隔?!纠縮bit型變量的定義:sbitOV=0xd2;sbitCY=oxd7;unsignedcharbdataflag;sbitflag0=flag^0;sfrP1=0x90;sbitP1_0=P1^0;sbitP1_1=P1^1;sbitP1_2=P1^2;sbitP1_3=P1^3;sbitP1_4=P1^4;sbitP1_5=P1^5;sbitP1_6=P1^6;sbitP1_7=P1^7;sbit位類型符用于定義在可位尋址字節(jié)或特殊功能31在C51中,為了用戶處理方便,C51編譯器把MCS-51單片機的常用的特殊功能寄存器和特殊位進行了定義,放在一個“reg51.h”或“reg52.h”的頭文件中,當(dāng)用戶要使用時,只須要在使用之前用一條預(yù)處理命令#include<reg52.h>把這個頭文件包含到程序中,然后就可使用殊功能寄存器名和特殊位名稱。在C51中,為了用戶處理方便,C51編譯器把M324.3.3存儲模式C51編譯器支持三種存儲模式:SMALL模式、COMPACT模式和LARGE模式。不同的存儲模式對變量默認(rèn)的存儲器類型不一樣。(1)SMALL模式。SMALL模式稱為小編譯模式,在SMALL模式下,編譯時,函數(shù)參數(shù)和變量被默認(rèn)在片內(nèi)RAM中,存儲器類型為data。(2)COMPACT模式。COMPACT模式稱為緊湊編譯模式,在COMPACT模式下,編譯時,函數(shù)參數(shù)和變量被默認(rèn)在片外RAM的低256字節(jié)空間,存儲器類型為pdata。(3)LARGE模式。LARGE模式稱為大編譯模式,在LARGE模式下,編譯時函數(shù)參數(shù)和變量被默認(rèn)在片外RAM的64K字節(jié)空間,存儲器類型為xdata。4.3.3存儲模式C51編譯器支持三種存儲33在程序中變量的存儲模式的指定通過#pragma預(yù)處理命令來實現(xiàn)。函數(shù)的存儲模式可通過在函數(shù)定義時后面帶存儲模式說明。如果沒有指定,則系統(tǒng)都隱含為SMALL模式?!纠孔兞康拇鎯δJ健?pragmasmall/*變量的存儲模式為SMALL*/chark1;intxdatam1;#pragmacompact/*變量的存儲模式為SMALL*/chark2;intxdatam2;intfunc1(intx1,inty1)large/*函數(shù)的存儲模式為LARGE*/{return(x1+y1);}intfunc2(intx2,inty2)/*函數(shù)的存儲模式隱含為SMALL*/{return(x2-y2);}程序編譯時,k1變量存儲器類型為data,k2變量存儲器類型為pdata,而m1和m2由于定義時帶了存儲器類型xdata,因而它們?yōu)閤data型;函數(shù)func1的形參x1和y1的存儲器類型為xdata型,而函數(shù)func2由于沒有指明存儲模式,隱含為SMALL模式,形參x2和y2的存儲器類型為data。在程序中變量的存儲模式的指定通過#pragma預(yù)處理命令來實344.3.4絕對地址的訪問一.使用C51運行庫中預(yù)定義宏C51編譯器提供了一組宏定義來對51系列單片機的code、data、pdata和xdata空間進行絕對尋址。規(guī)定只能以無符號數(shù)方式訪問,定義了8個宏定義,其函數(shù)原型如下:4.3.4絕對地址的訪問一.使用C51運行庫中預(yù)定義宏35#defineCBYTE((unsignedcharvolatile*)0x50000L)#defineDBYTE((unsignedcharvolatile*)0x40000L)#definePBYTE((unsignedcharvolatile*)0x30000L)#defineXBYTE((unsignedcharvolatile*)0x20000L)#defineCWORD((unsignedintvolatile*)0x50000L)#defineDWORD((unsignedintvolatile*)0x40000L)#definePWORD((unsignedintvolatile*)0x30000L)#defineXWORD((unsignedintvolatile*)0x20000L)

這些函數(shù)原型放在absacc.h文件中。使用時須用預(yù)處理命令把該頭文件包含到文件中,形式為:#include<absacc.h>。其中:CBYTE以字節(jié)形式對code區(qū)尋址,DBYTE以字節(jié)形式對data區(qū)尋址,PBYTE以字節(jié)形式對pdata區(qū)尋址,XBYTE以字節(jié)形式對xdata區(qū)尋址,CWORD以字形式對code區(qū)尋址,DWORD以字形式對data區(qū)尋址,PWORD以字形式對pdata區(qū)尋址,XWORD以字形式對xdata區(qū)尋址。#defineCBYTE((unsignedch36【例】絕對地址對存儲單元的訪問#include<absacc.h>/*將絕對地址頭文件包含在文件中*/#include<reg52.h>/*將寄存器頭文件包含在文件中*/#defineucharunsignedchar/*定義符號uchar為數(shù)據(jù)類型符unsignedchar*/#defineuintunsignedint/*定義符號uint為數(shù)據(jù)類型符unsignedint*/voidmain(void){ucharvar1;uintvar2;var1=XBYTE[0x0005];/*XBYTE[0x0005]訪問片外RAM的0005字節(jié)單元*/var2=XWORD[0x0002];/*XWORD[0x0002]訪問片外RAM的000字單元*/......while(1);}

在上面程序中,其中XBYTE[0x0005]就是以絕對地址方式訪問的片外RAM0005字節(jié)單元;XWORD[0x0002]就是以絕對地址方式訪問的片外RAM0002字單元?!纠拷^對地址對存儲單元的訪問在上面程序中,其中XBYTE[37【例】通過指針實現(xiàn)絕對地址的訪問。#defineucharunsignedchar/*定義符號uchar為數(shù)據(jù)類型符unsignedchar*/#defineuintunsignedint/*定義符號uint為數(shù)據(jù)類型符unsignedint*/voidfunc(void){uchardatavar1;ucharpdata*dp1;/*定義一個指向pdata區(qū)的指針dp1*/uintxdata*dp2;/*定義一個指向xdata區(qū)的指針dp2*/uchardata*dp3;/*定義一個指向data區(qū)的指針dp3*/dp1=0x30;/*dp1指針賦值,指向pdata區(qū)的30H單元*/dp2=0x1000;/*dp2指針賦值,指向xdata區(qū)的1000H單元*/*dp1=0xff;/*將數(shù)據(jù)0xff送到片外RAM30H單元*/*dp2=0x1234;/*將數(shù)據(jù)0x1234送到片外RAM1000H單元*/dp3=&var1;/*dp3指針指向data區(qū)的var1變量*/*dp3=0x20;/*給變量var1賦值0x20*/}二.通過指針訪問采用指針的方法,可以實現(xiàn)在C51程序中對任意指定的存儲器單元進行訪問。【例】通過指針實現(xiàn)絕對地址的訪問。二.通過指針訪問38三.使用C51擴展關(guān)鍵字_at_使用_at_對指定的存儲器空間的絕對地址進行訪問,一般格式如下:

[存儲器類型]數(shù)據(jù)類型說明符變量名_at_地址常數(shù);其中,存儲器類型為data、bdata、idata、pdata等C51能識別的數(shù)據(jù)類型,如省略則按存儲模式規(guī)定的默認(rèn)存儲器類型確定變量的存儲器區(qū)域;數(shù)據(jù)類型為C51支持的數(shù)據(jù)類型。地址常數(shù)用于指定變量的絕對地址,必須位于有效的存儲器空間之內(nèi);使用_at_定義的變量必須為全局變量。三.使用C51擴展關(guān)鍵字_at_39【例】通過_at_實現(xiàn)絕對地址的訪問。#defineucharunsignedchar/*定義符號uchar為數(shù)據(jù)類型符unsignedchar*/#defineuintunsignedint/*定義符號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);}【例】通過_at_實現(xiàn)絕對地址的訪問。404.4C51的運算符及表達式4.4.1賦值運算符賦值運算符“=”,在C51中,它的功能是將一個數(shù)據(jù)的值賦給一個變量,如x=10。利用賦值運算符將一個變量與一個表達式連接起來的式子稱為賦值表達式,在賦值表達式的后面加一個分號“;”就構(gòu)成了賦值語句,一個賦值語句的格式如下:

變量=表達式;執(zhí)行時先計算出右邊表達式的值,然后賦給左邊的變量。例如:x=8+9;/*將8+9的值賦紿變量x*/x=y=5;/*將常數(shù)5同時賦給變量x和y*/在C51中,允許在一個語句中同時給多個變量賦值,賦值順序自右向左。4.4C51的運算符及表達式4.4.1賦值運算符414.4.2算術(shù)運算符C51中支持的算術(shù)運算符有: +加或取正值運算符 -減或取負(fù)值運算符*乘運算符 /除運算符%取余運算符加、減、乘運算相對比較簡單,而對于除運算,如相除的兩個數(shù)為浮點數(shù),則運算的結(jié)果也為浮點數(shù),如相除的兩個數(shù)為整數(shù),則運算的結(jié)果也為整數(shù),即為整除。如25.0/20.0結(jié)果為1.25,而25/20結(jié)果為1。對于取余運算,則要求參加運算的兩個數(shù)必須為整數(shù),運算結(jié)果為它們的余數(shù)。例如:x=5%3,結(jié)果x的值為2。4.4.2算術(shù)運算符424.4.3關(guān)系運算符C51中有6種關(guān)系運算符: >大于 <小于 >=大于等于 <=小于等于 ==等于 !=不等于關(guān)系運算用于比較兩個數(shù)的大小,用關(guān)系運算符將兩個表達式連接起來形成的式子稱為關(guān)系表達式。關(guān)系表達式通常用來作為判別條件構(gòu)造分支或循環(huán)程序。關(guān)系表達式的一般形式如下:

表達式1關(guān)系運算符表達式2關(guān)系運算的結(jié)果為邏輯量,成立為真(1),不成立為假(0)。其結(jié)果可以作為一個邏輯量參與邏輯運算。例如:5>3,結(jié)果為真(1),而10==100,結(jié)果為假(0)。注意:關(guān)系運算符等于“==”是由兩個“=”組成。4.4.3關(guān)系運算符434.4.4邏輯運算符C51有3種邏輯運算符: ||邏輯或 &&邏輯與 !邏輯非關(guān)系運算符用于反映兩個表達式之間的大小關(guān)系,邏輯運算符則用于求條件式的邏輯值,用邏輯運算符將關(guān)系表達式或邏輯量連接起來的式子就是邏輯表達式。

邏輯與,格式:條件式1&&條件式2當(dāng)條件式1與條件式2都為真時結(jié)果為真(非0值),否則為假(0值)。邏輯或,格式:條件式1||條件式2當(dāng)條件式1與條件式2都為假時結(jié)果為假(0值),否則為真(非0值)。邏輯非,格式:!條件式當(dāng)條件式原來為真(非0值),邏輯非后結(jié)果為假(0值)。當(dāng)條件式原來為假(0值),邏輯非后結(jié)果為真(非0值)。例如:若a=8,b=3,c=0,則!a為假,a&&b為真,b&&c為假。4.4.4邏輯運算符邏輯與,格式:444.4.5位運算符【例】設(shè)a=0x45=01010100B,b=0x3b=00111011B,則a&b、a|b、a^b、~a、a<<2、b>>2分別為多少?a&b=00010000b=0x10。a|b=01111111B=0x7f。a^b=01101111B=0x6f。~a=10101011B=0xab。a<<2=01010000B=0x50。b>>2=00001110B=0x0e。C51語言能對運算對象按位進行操作,它與匯編語言使用一樣方便。位運算是按位對變量進行運算,但并不改變參與運算的變量的值。如果要求按位改變變量的值,則要利用相應(yīng)的賦值運算。C51中位運算符只能對整數(shù)進行操作,不能對浮點數(shù)進行操作。C51中的位運算符有:&按位與|按位或^按位異或~按位取反<<左移>>右移4.4.5位運算符【例】設(shè)a=0x45=01010100454.4.6復(fù)合賦值運算符C51語言中支持在賦值運算符“=”的前面加上其它運算符,組成復(fù)合賦值運算符。下面是C51中支持的復(fù)合賦值運算符+=加法賦值+減法賦值*=乘法賦值/=除法賦值%=取模賦值&=邏輯與賦值|=邏輯或賦值^=邏輯異或賦值~=邏輯非賦值>>=右移位賦值<<=左移位賦值復(fù)合賦值運算的一般格式如下:變量復(fù)合運算賦值符表達式它的處理過程:先把變量與后面的表達式進行某種運算,然后將運算的結(jié)果賦給前面的變量。其實這是C51語言中簡化程序的一種方法,大多數(shù)二目運算都可以用復(fù)合賦值運算符簡化表示。例如:a+=6相當(dāng)于a=a+6;a*=5相當(dāng)于a=a*5;b&=0x55相當(dāng)于b=b&0x55;x>>=2相當(dāng)于x=x>>2。4.4.6復(fù)合賦值運算符464.4.7逗號運算符在C51語言中,逗號“,”是一個特殊的運算符,可以用它將兩個或兩個以上的表達式連接起來,稱為逗號表達式。逗號表達式的一般格式為:表達式1,表達式2,……,表達式n程序執(zhí)行時對逗號表達式的處理:按從左至右的順序依次計算出各個表達式的值,而整個逗號表達式的值是最右邊的表達式(表達式n)的值。例如:x=(a=3,6*3)結(jié)果x的值為18。4.4.7逗號運算符474.4.8條件運算符條件運算符“?:”是C51語言中唯一的一個三目運算符,它要求有三個運算對象,用它可以將三個表達式連接在一起構(gòu)成一個條件表達式。條件表達式的一般格式為:邏輯表達式?表達式1:表達式2其功能是先計算邏輯表達式的值,當(dāng)邏輯表達式的值為真(非0值)時,將計算的表達式1的值作為整個條件表達式的值;當(dāng)邏輯表達式的值為假(0值)時,將計算的表達式2的值作為整個條件表達式的值。例如:條件表達式max=(a>b)?a:b的執(zhí)行結(jié)果是將a和b中較大的數(shù)賦值給變量max。4.4.8條件運算符48指針是C51語言中的一個十分重要的概念,在C51中的數(shù)據(jù)類型中專門有一種指針類型。指針為變量的訪問提供了另一種方式,變量的指針就是該變量的地址,還可以定義一個專門指向某個變量的地址的指針變量。4.4.9指針與地址運算符指針是C51語言中的一個十分重要的概念,在C51中的49為了表示指針變量和它所指向的變量地址之間的關(guān)系,C51中提供了兩個專門的運算符: *指針運算符 &取地址運算符指針運算符“*”放在指針變量前面,通過它實現(xiàn)訪問以指針變量的內(nèi)容為地址所指向的存儲單元。例如:指針變量p中的地址為2000H,則*p所訪問的是地址為2000H的存儲單元,x=*p,實現(xiàn)把地址為2000H的存儲單元的內(nèi)容送給變量x。取地址運算符“&”放在變量的前面,通過它取得變量的地址,變量的地址通常送給指針變量。例如:設(shè)變量x的內(nèi)容為12H,地址為2000H,則&x的值為2000H,如有一指針變量p,則通常用p=&x,實現(xiàn)將x變量的地址送給指針變量p,指針變量p指向變量x,以后可以通過*p訪問變量x。為了表示指針變量和它所指向的變量地址之間的關(guān)系504.5表達式語句及復(fù)合語句4.5.1表達式語句在表達式的后邊加一個分號“;”就構(gòu)成了表達式語句,如: a=++b*9; x=8;y=7; ++k;可以一行放一個表達式形成表達式語句,也可以一行放多個表達式形成表達式語句,這時每個表達式后面都必須帶“;”號,另外,還可以僅由—個分號“;”占一行形成一個表達式語句,這種語句稱為空語句。4.5表達式語句及復(fù)合語句4.5.1表達式語句51空語句在程序設(shè)計中通常用于兩種情況:(1)在程序中為有關(guān)語句提供標(biāo)號,用以標(biāo)記程序執(zhí)行的位置。例如采用下面的語句可以構(gòu)成一個循環(huán)。repeat:;;gotorepeat;(2)在用while語句構(gòu)成的循環(huán)語句后面加一個分號,形成一個不執(zhí)行其它操作的空循環(huán)體。這種結(jié)構(gòu)通常用于對某位進行判斷,當(dāng)不滿足條件則等待,滿足條件則執(zhí)行??照Z句在程序設(shè)計中通常用于兩種情況:52【例】下面這段子程序用于讀取8051單片機的串行口的數(shù)據(jù),當(dāng)沒有接收到則等待,當(dāng)接收到,接收數(shù)據(jù)后返回,返回值為接收的數(shù)據(jù)。#include<reg51.h>chargetchar(){charc;while(!RI);//當(dāng)接收中斷標(biāo)志位RI為0則等待,當(dāng)接收中斷標(biāo)志位為1則;等待結(jié)束c=SBUF;RI=0;return(c);}【例】下面這段子程序用于讀取8051單片機的串行口的數(shù)據(jù),當(dāng)534.5.2復(fù)合語句復(fù)合語句是由若干條語句組合而成的一種語句,在C51中,用一個大括號“{}”將若干條語句括在一起就形成了一個復(fù)合語句,復(fù)合語句最后不需要以分號“;”結(jié)束,但它內(nèi)部的各條語句仍需以分號“;”結(jié)束。復(fù)合語句的一般形式為:{局部變量定義;語句l;語句2;}

4.5.2復(fù)合語句復(fù)合語句是由若干條語句組合54復(fù)合語句在執(zhí)行時,其中的各條單語句按順序依次執(zhí)行,整個復(fù)合語句在語法上等價于一條單語句,因此在C51中可以將復(fù)合語句視為一條單語句。通常復(fù)合語句出現(xiàn)在函數(shù)中,實際上,函數(shù)的執(zhí)行部分(即函數(shù)體)就是一個復(fù)合語句;復(fù)合語句中的單語句一般是可執(zhí)行語句,此外還可以是變量的定義語句(說明變量的數(shù)據(jù)類型)。在復(fù)合語句內(nèi)部語句所定義的變量,稱為該復(fù)合語句中的局部變量,它僅在當(dāng)前這個復(fù)合語句中有效。利用復(fù)合語句將多條單語句組合在—起,以及在復(fù)合語句中進行局部變量定義是C51語言的一個重要特征。復(fù)合語句在執(zhí)行時,其中的各條單語句按順序依次執(zhí)554.6C51的輸入輸出在C51語言中,它本身不提供輸入和輸出語句,輸入和輸出操作是由函數(shù)來實現(xiàn)的。在C51的標(biāo)準(zhǔn)函數(shù)庫中提供了一個名為“stdio.h”的一般I/O函數(shù)庫,它當(dāng)中定義了C51中的輸入和輸出函數(shù)。當(dāng)對輸入和輸出函數(shù)使用時,須先用預(yù)處理命令“#include<stdio.h>”將該函數(shù)庫包含到文件中。4.6C51的輸入輸出在C51語言中,它本56在C51的一般I/O函數(shù)庫中定義的I/O函數(shù)都是通過串行接口實現(xiàn),在使用I/O函數(shù)之前,應(yīng)先對MCS-51單片機的串行接口進行初始化。選擇串口工作于方式2(8位自動重載方式),波特率由定時器/計數(shù)器1溢出率決定。例如,設(shè)系統(tǒng)時鐘為12MHZ,波特率為2400,則初始化程序如下: SCON=0x52; TMOD=0X20; TH1=0xf3; TR1=1;在C51的一般I/O函數(shù)庫中定義的I/O函數(shù)都是通過574.6.1格式輸出函數(shù)printf()printf()函數(shù)的的作用是通過串行接口輸出若干任意類型的數(shù)據(jù),它的格式如下:printf(格式控制,輸出參數(shù)表)格式控制是用雙引號括起來的字符串,也稱轉(zhuǎn)換控制字符串,它包括三種信息:格式說明符、普通字符和轉(zhuǎn)義字符。(1)格式說明符,由“%”和格式字符組成,它的作用是用于指明輸出的數(shù)據(jù)的格式輸出,如%d、%f等,它們的具體情況見下表。(2)普通字符,這些字符按原樣輸出,用來輸出某些提示信息。(3)轉(zhuǎn)義字符,就是前面介紹的轉(zhuǎn)義字符(下表),用來輸出特定的控制符,如輸出轉(zhuǎn)義字符\n就是使輸出換一行。輸出參數(shù)表是需要輸出的一組數(shù)據(jù),可以是表達式。4.6.1格式輸出函數(shù)printf()print58格式字符數(shù)據(jù)類型輸出格式dint帶符號十進制數(shù)uint無符號十進制數(shù)oint無符號八進制數(shù)xint無符號十六進制數(shù),用“a~f”表示Xint無符號十六進制數(shù),用“A~F”表示ffloat帶符號十進制數(shù)浮點數(shù),形式為[-]dddd.dddde,Efloat帶符號十進制數(shù)浮點數(shù),形式為[-]d.ddddEddg,Gfloat自動選擇e或f格式中更緊湊的一種輸出格式cchar單個字符s指針指向一個帶結(jié)束符的字符串p指針帶存儲器批示符和偏移量的指針,形式為M:aaaa。其中,M可分別為:C(code),D(data),I(idata),P(pdata),如M為a,則表示的是指針偏移量格式字符數(shù)據(jù)類型輸出格式dint帶符號十進制數(shù)uint無符號594.6.2格式輸入函數(shù)scanf()scanf()函數(shù)的作用是通過串行接口實現(xiàn)數(shù)據(jù)輸入,它的使用方法與printf()類似,scanf()的格式如下:scanf(格式控制,地址列表)格式控制與printf()函數(shù)的情況類似,也是用雙引號括起來的一些字符,可以包括以下三種信息:空白字符、普通字符和格式說明。(1)空白字符,包含空格、制表符、換行符等,這些字符在輸出時被忽略。(2)普通字符,除了以百分號“%”開頭的格式說明符而外的所有非空白字符,在輸入時要求原樣輸入。(3)格式說明,由百分號“%”和格式說明符組成,用于指明輸入數(shù)據(jù)的格式,它的基本情況與printf()相同,具體情況見表4-5。地址列表是由若干個地址組成,它可以是指針變量、取地址運算符“&”加變量(變量的地址)或字符串名(表示字符串的首地址)。4.6.2格式輸入函數(shù)scanf()scanf60格式字符數(shù)據(jù)類型輸出格式dint指針帶符號十進制數(shù)uint指針無符號十進制數(shù)oint指針無符號八進制數(shù)xint指針無符號十六進制數(shù)f,e,Efloat指針浮點數(shù)cchar指針字符sstring指針字符串格式字符數(shù)據(jù)類型輸出格式dint指針帶符號十進制數(shù)uint指61【例12】使用格式輸入輸出函數(shù)的例子#include<reg52.h>//包含特殊功能寄存器庫#include<stdio.h>//包含I/O函數(shù)庫voidmain(void)//主函數(shù){intx,y;//定義整型變量x和ySCON=0x52;//串口初始化TMOD=0x20;TH1=0XF3;TR1=1;printf(“inputx,y:\n”);//輸出提示信息scanf(“%d%d”,&x,&y);//輸入x和y的值printf(“\n”);//輸出換行printf(“%d+%d=%d”,x,y,x+y);//按十進制形式輸出printf(“\n”);//輸出換行printf(“%xH+%xH=%XH”,x,y,x+y);//按十六進制形式輸出while(1);//結(jié)束}【例12】使用格式輸入輸出函數(shù)的例子624.7C51程序基本結(jié)構(gòu)與相關(guān)語句4.7.1C51的基本結(jié)構(gòu)一.順序結(jié)構(gòu)順序結(jié)構(gòu)是最基本、最簡單的結(jié)構(gòu),在這種結(jié)構(gòu)中,程序由低地址到高地址依次執(zhí)行,如圖給出順序結(jié)構(gòu)流程圖,程序先執(zhí)行A操作,然后再執(zhí)行B操作。AB圖:順序結(jié)構(gòu)流程圖4.7C51程序基本結(jié)構(gòu)與相關(guān)語句4.7.1C51的63選擇結(jié)構(gòu)可使程序根據(jù)不同的情況,選擇執(zhí)行不同的分支,在選擇結(jié)構(gòu)中,程序先都對一個條件進行判斷。當(dāng)條件成立,即條件語句為“真”時,執(zhí)行一個分支,當(dāng)條件不成立時,即條件語句為“假”時,執(zhí)行另一個分支。如圖4.4,當(dāng)條件S成立時,執(zhí)行分支A,當(dāng)條件P不成立時,執(zhí)行分支B。二.選擇結(jié)構(gòu)條件P語句A語句B成立不成立

在C51中,實現(xiàn)選擇結(jié)構(gòu)的語句為if/else,if/elseif語句。另外在C51中還支持多分支結(jié)構(gòu),多分支結(jié)構(gòu)既可以通過if和elseif語句嵌套實現(xiàn),可用swith/case語句實現(xiàn)。選擇結(jié)構(gòu)可使程序根據(jù)不同的情況,選擇執(zhí)行不同的分支64在程序處理過程中,有時需要某一段程序重復(fù)執(zhí)行多次,這時就需要循環(huán)結(jié)構(gòu)來實現(xiàn),循環(huán)結(jié)構(gòu)就是能夠使程序段重復(fù)執(zhí)行的結(jié)構(gòu)。循環(huán)結(jié)構(gòu)又分為兩種:當(dāng)(while)型循環(huán)結(jié)構(gòu)和直到(do...while)型循環(huán)結(jié)構(gòu)。(1)當(dāng)型循環(huán)結(jié)構(gòu)當(dāng)型循環(huán)結(jié)構(gòu)如圖4-3,當(dāng)條件P成立(為“真”)時,重復(fù)執(zhí)行語句A,當(dāng)條件不成立(為“假”)時才停止重復(fù),執(zhí)行后面的程序。三.循環(huán)結(jié)構(gòu)條件P語句A成立不成立圖:當(dāng)型循環(huán)結(jié)構(gòu)

在程序處理過程中,有時需要某一段程序重復(fù)執(zhí)行多65(2)直到型循環(huán)結(jié)構(gòu)直到型循環(huán)結(jié)構(gòu)如圖4,先執(zhí)行語句A,再判斷條件P,當(dāng)條件成立(為“真”)時,再重復(fù)執(zhí)行語句A,直到條件不成立(為“假”)時才停止重復(fù),執(zhí)行后面的程序。條件P語句A成立不成立圖:直到型循環(huán)結(jié)構(gòu)構(gòu)成循環(huán)結(jié)構(gòu)的語句主要有:while、dowhile、for、goto等。(2)直到型循環(huán)結(jié)構(gòu)條件P語句A成立不成立圖:直到型循環(huán)結(jié)構(gòu)664.7.2if語句if語句是C51中的一個基本條件選擇語句,它通常有三種格式:(1)if(表達式){語句;}(2)if(表達式){語句1;}else{語句2;}(3)if(表達式1){語句1;}elseif(表達式2)(語句2;)elseif(表達式3)(語句3;)……elseif(表達式n-1)(語句n-1;)else{語句n}4.7.2if語句67【例13】if語句的用法。(1)if(x!=y)printf(“x=%d,y=%d\n”,x,y);執(zhí)行上面語句時,如果x不等于y,則輸出x的值和y的值。(2)if(x>y)max=x;elsemax=y;執(zhí)行上面語句時,如x大于y成立,則把x送給最大值變量max,如x大于y不成立,則把y送給最大值變量max。使max變量得到x、y中的大數(shù)。(3)if(score>=90)printf(“YourresultisanA\n”);elseif(score>=80)printf(“YourresultisanB\n”);elseif(score>=70)printf(“YourresultisanC\n”);elseif(score>=60)printf(“YourresultisanD\n”);elseprintf(“YourresultisanE\n”);執(zhí)行上面語句后,能夠根據(jù)分?jǐn)?shù)score分別打出A、B、C、D、E五個等級?!纠?3】if語句的用法。684.7.3switch/case語句if語句通過嵌套可以實現(xiàn)多分支結(jié)構(gòu),但結(jié)構(gòu)復(fù)雜。switch是C51中提供的專門處理多分支結(jié)構(gòu)的多分支選擇語句。它的格式如下:switch(表達式){case常量表達式1:{語句1;}break;case常量表達式2:{語句2;}break;……case常量表達式n:{語句n;}break;default:{語句n+1;}4.7.3switch/case語句if語句通過嵌69說明如下:(1)switch后面括號內(nèi)的表達式,可以是整型或字符型表達式。(2)當(dāng)該表達式的值與某一“case”后面的常量表達式的值相等時,就執(zhí)行該“case”后面的語句,然后遇到break語句退出switch語句。若表達式的值與所有case后的常量表達式的值都不相同,則執(zhí)行default后面的語句,然后退出switch結(jié)構(gòu)。(3)每一個case常量表達式的值必須不同否則會出現(xiàn)自相矛盾的現(xiàn)象。(4)case語句和default語句的出現(xiàn)次序?qū)?zhí)行過程沒有影響。(5)每個case語句后面可以有“break”,也可以沒有。有break語句,執(zhí)行到break則退出switch結(jié)構(gòu),若沒有,則會順次執(zhí)行后面的語句,直到遇到break或結(jié)束。(6)每一個case語句后面可以帶一個語句,也可以帶多個語句,還可以不帶。語句可以用花括號括起,也可以不括。(7)多個case可以共用一組執(zhí)行語句。說明如下:70【例14】switch/case語句的用法。對學(xué)生成績劃分為A~D,對應(yīng)不同的百分制分?jǐn)?shù),要求根據(jù)不同的等級打印出它的對應(yīng)百分?jǐn)?shù)??梢酝ㄟ^下面的switch/case語句實現(xiàn)。……switch(grade){case‘A’;printf(”90~100\n”);break;case‘B’;printf(”80~90\n”);break;case‘C’;printf(”70~80\n”);break;case‘D’;printf(”60~70\n”);break;case‘E’;printf(”<60\n”);break;default;printf(”error”\n)}【例14】switch/case語句的用法。714.7.4while語句while語句在C51中用于實現(xiàn)當(dāng)型循環(huán)結(jié)構(gòu),它的格式如下:while(表達式){語句;}/*循環(huán)體*/while語句后面的表達式是能否循環(huán)的條件,后面的語句是循環(huán)體。當(dāng)表達式為非0(真)時,就重復(fù)執(zhí)行循環(huán)體內(nèi)的語句;當(dāng)表達式為0(假),則中止while循環(huán),程序?qū)?zhí)行循環(huán)結(jié)構(gòu)之外的下一條語句。它的特點是:先判斷條件,后執(zhí)行循環(huán)體。在循環(huán)體中對條件進行改變,然后再判斷條件,如條件成立,則再執(zhí)行循環(huán)體,如條件不成立,則退出循環(huán)。如條件第一次就不成立,則循環(huán)體一次也不執(zhí)行。4.7.4while語句while語句在C572#include<reg52.h>//包含特殊功能寄存器庫#include<stdio.h>//包含I/O函數(shù)庫voidmain(void)//主函數(shù){inti,s=0;//定義整型變量x和yi=1;SCON=0x52;//串口初始化TMOD=0x20;TH1=0XF3;TR1=1;while(i<=100)//累加1~100之和在s中{s=s+i;i++;}printf(“1+2+3……+100=%d\n”,s);while(1);}【例15】下面程序是通過while語句實現(xiàn)計算并輸出1~100的累加和。程序執(zhí)行的結(jié)果:1+2+3……+100=5050#include<reg52.h>//包含特殊功能寄734.7.5dowhile語句dowhile語句在C51中用于實現(xiàn)直到型循環(huán)結(jié)構(gòu),它的格式如下:do{語句;}/*循環(huán)體*/while(表達式);它的特點是:先執(zhí)行循環(huán)體中的語句,后判斷表達式。如表達式成立(真),則再執(zhí)行循環(huán)體,然后又判斷,直到有表達式不成立(假)時,退出循環(huán),執(zhí)行dowhile結(jié)構(gòu)的下一條語句。dowhile語句在執(zhí)行時,循環(huán)體內(nèi)的語句至少會被執(zhí)行一次。4.7.5dowhile語句dowhi74#include<reg52.h>//包含特殊功能寄存器庫#include<stdio.h>//包含I/O函數(shù)庫voidmain(void)//主函數(shù){inti,s=0;//定義整型變量x和yi=1;SCON=0x52;//串口初始化TMOD=0x20;TH1=0XF3;TR1=1;do//累加1~100之和在s中{s=s+i;i++;}while(i<=100);printf(“1+2+3……+100=%d\n”,s);while(1);}【例16】通過dowhile語句實現(xiàn)計算并輸出1~100的累加和。#include<reg52.h>//包含特殊功能寄75for(表達式1;表達式2;表達式3){語句;}/*循環(huán)體*/for語句后面帶三個表達式,它的執(zhí)行過程如下:(1)先求解表達式1的值。(2)求解表達式2的值,如表達式2的值為真,則執(zhí)行循環(huán)休中的語句,然后執(zhí)行下一步(3)的操作,如表達式2的值為假,則結(jié)束for循環(huán),轉(zhuǎn)到最后一步。(3)若表達式2的值為真,則執(zhí)行完循環(huán)體中的語句后,求解表達式3,然后轉(zhuǎn)到第四步。(4)轉(zhuǎn)到(2)繼續(xù)執(zhí)行。(5)退出for循環(huán),執(zhí)行下面的一條語句。在for循環(huán)中,一般表達式1為初值表達式,用于給循環(huán)變量賦初值;表達式2為條件表達式,對循環(huán)變量進行判斷;表達式3為循環(huán)變量更新表達式,用于對循環(huán)變量的值進行更新,使循環(huán)變量能不滿足條件而退出循環(huán)。4.7.6for語句for(表達式1;表達式2;表達式3)4.7.6for語76【例17】用for語句實現(xiàn)計算并輸出1~100的累加和。#include<reg52.h>//包含特殊功能寄存器庫#include<stdio.h>//包含I/O函數(shù)庫voidmain(void)//主函數(shù){inti,s=0;//定義整型變量x和ySCON=0x52;//串口初始化TMOD=0x20;TH1=0XF3;TR1=1;for(i=1;i<=100;i++)s=s+i;//累加1~100之和在s中printf(“1+2+3……+100=%d\n”,s);while(1);}程序執(zhí)行的結(jié)果:1+2+3……+100=5050【例17】用for語句實現(xiàn)計算并輸出1~100的累加和。程77在一個循環(huán)的循環(huán)體中允許又包含一個完整的循環(huán)結(jié)構(gòu),這種結(jié)構(gòu)稱為循環(huán)的嵌套。外面的循環(huán)稱為外循環(huán),里面的循環(huán)稱為內(nèi)循環(huán),如果在內(nèi)循環(huán)的循環(huán)體內(nèi)又包含循環(huán)結(jié)構(gòu),就構(gòu)成了多重循環(huán)。在C51中,允許三種循環(huán)結(jié)構(gòu)相互嵌套。【例18】用嵌套結(jié)構(gòu)構(gòu)造一個延時程序。voiddelay(unsignedintx){unsignedcharj;while(x--){for(j=0;j<125;j++);}}這里,用內(nèi)循環(huán)構(gòu)造一個基準(zhǔn)的延時,調(diào)用時通過參數(shù)設(shè)置外循環(huán)的次數(shù),這樣就可以形成各種延時關(guān)系。4.7.7循環(huán)的嵌套在一個循環(huán)的循環(huán)體中允許又包含一個完整的循環(huán)結(jié)構(gòu),78break和continue語句通常用于循環(huán)結(jié)構(gòu)中,用來跳出循環(huán)結(jié)構(gòu)。但是二者又有所不同,下面分別介紹。1.break語句前面已介紹過用break語句可以跳出switch結(jié)構(gòu),使程序繼續(xù)執(zhí)行switch結(jié)構(gòu)后面的一個語句。使用break語句還可以從循環(huán)體中跳出循環(huán),提前結(jié)束循環(huán)而接著執(zhí)行循環(huán)結(jié)構(gòu)下面的語句。它不能用在除了循環(huán)語句和switch語句之外的任何其它語句中。【例19】下面一段程序用于計算圓的面積,當(dāng)計算到面積大于100時,由break語句跳出循環(huán)。for(r=1;r<=10;r++){area=pi*r*r;if(area>100)break;printf(“%f\n”,area);}4.7.8break和continue語句break和continue語句通常用于循環(huán)結(jié)構(gòu)中79continue語句用在循環(huán)結(jié)構(gòu)中,用于結(jié)束本次循環(huán),跳過循環(huán)體中continue下面尚未執(zhí)行的語句,直接進行下一次是否執(zhí)行循環(huán)的判定。continue語句和break語句的區(qū)別在于:continue語句只是結(jié)束本次循環(huán)而不是終止整個循環(huán);break語句則是結(jié)束循環(huán),不再進行條件判斷?!纠?0】輸出100~200間不能被3整除的數(shù)。for(i=100;i<=200;i++){if(i%3==0)continue;printf(“%d”;i);}在程序中,當(dāng)i能被3整除時,執(zhí)行continue語句,結(jié)束本次循環(huán),跳過printf()函數(shù),只有能被3整除時才執(zhí)行printf()函數(shù)。2.continue語句continue語句用在循環(huán)結(jié)構(gòu)中,用于結(jié)束本次循80return語句一般放在函數(shù)的最后位置,用于終止函數(shù)的執(zhí)行,并控制程序返回調(diào)用該函數(shù)時所處的位置。返回時還可以通過return語句帶回返回值。return語句格式有兩種:(1)return;(2)return(表達式);如果return語句后面帶有表達式,則要計算表達式的值,并將表達式的值作為函數(shù)的返回值。若不帶表達式,則函數(shù)返回時將返回一個不確定的值。通常我們用return語句把調(diào)用函數(shù)取得的值返回給主調(diào)用函數(shù)。4.7.8return語句return語句一般放在函數(shù)的最后位置,用于終止814.8函數(shù)4.8.1函數(shù)的定義函數(shù)定義的一般格式如下:函數(shù)類型函數(shù)名(形式參數(shù)表)[reentrant][interruptm][usingn]形式參數(shù)說明{ 局部變量定義 函數(shù)體}前面部件稱為函數(shù)的首部,后面稱為函數(shù)的尾部,格式說明:1.函數(shù)類型函數(shù)類型說明了函數(shù)返回值的類型。2.函數(shù)名函數(shù)名是用戶為自定義函數(shù)取的名字以便調(diào)用函數(shù)時使用。3.形式參數(shù)表形式參數(shù)表用于列錄在主調(diào)函數(shù)與被調(diào)用函數(shù)之間進行數(shù)據(jù)傳遞的形式參數(shù)。4.8函數(shù)4.8.1函數(shù)的定義函數(shù)定義的一般格式82【例21】定義一個返回兩個整數(shù)的最大值的函數(shù)max()。intmax(intx,inty){intz;z=x>y?x:y;return(z);}也可以用成這樣:intmax(x,y)intx,y;{intz;z=x>y?x:y;return(z);}【例21】定義一個返回兩個整數(shù)的最大值的函數(shù)max()。834.reentrant修飾符這個修飾符用于把函數(shù)定義為可重入函數(shù)。所謂可重入函數(shù)就是允許被遞歸調(diào)用的函數(shù)。函數(shù)的遞歸調(diào)用是指當(dāng)一個函數(shù)正被調(diào)用尚未返回時,又直接或間接調(diào)用函數(shù)本身。一般的函數(shù)不能做到這樣,只有重入函數(shù)才允許遞歸調(diào)用。

4.reentrant修飾符

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論