




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第3章單片機(jī)C語言開發(fā)基礎(chǔ)3.1C語言源程序的結(jié)構(gòu)特點(diǎn)3.2標(biāo)識(shí)符和關(guān)鍵字3.3數(shù)據(jù)類型與運(yùn)算符
任務(wù)3-1不同數(shù)據(jù)類型控制LED閃爍
任務(wù)3-2數(shù)據(jù)運(yùn)算的LED顯示3.4C語言的語句
任務(wù)3-3用if語句控制LED的亮滅狀態(tài)
任務(wù)3-4用for語句控制LED的循環(huán)亮滅狀態(tài)第3章單片機(jī)C語言開發(fā)基礎(chǔ)3.5C語言的數(shù)組
任務(wù)3-5用字符型數(shù)組實(shí)現(xiàn)LED循環(huán)亮滅3.6C語言的函數(shù)
任務(wù)3-6用函數(shù)實(shí)現(xiàn)LED流水速度控制3.7C語言的編譯預(yù)處理
任務(wù)3-7用宏定義方式實(shí)現(xiàn)LED顯示本章小結(jié)習(xí)題
3.1C語言源程序的結(jié)構(gòu)特點(diǎn)
在計(jì)算機(jī)中,所有的指令、數(shù)據(jù)都是用二進(jìn)制代碼來表示的。這種用二進(jìn)制代碼表示的指令系統(tǒng)稱為機(jī)器語言,用機(jī)器語言編寫的程序稱為機(jī)器語言程序或“目標(biāo)程序”。對(duì)于計(jì)算機(jī),機(jī)器語言能被直接識(shí)別并快速執(zhí)行。但對(duì)于使用者,這種用機(jī)器語言編寫的程序很難識(shí)別和記憶,容易出錯(cuò)。為了克服這些缺點(diǎn),出現(xiàn)了匯編語言和高級(jí)語言。
匯編語言是一種用文字助記符來表示機(jī)器指令的符號(hào)語言,可以說是最接近機(jī)器碼的一種單片機(jī)編程語言,主要優(yōu)點(diǎn)是占用資源少,程序執(zhí)行率高,當(dāng)然也由于一條指令就對(duì)應(yīng)一條機(jī)器碼,所以每一步的執(zhí)行動(dòng)作都是比較清楚的,調(diào)試起來也是比較方便的。但對(duì)于程序開發(fā)來說,不同類型的單片機(jī),其匯編語言是有差異的。程序員寫出的匯編語言程序的確有執(zhí)行效率高的優(yōu)點(diǎn),但匯編語言的可移植性和可讀性差的特點(diǎn),使得開發(fā)出來的產(chǎn)品在維護(hù)和功能升級(jí)時(shí)有極大的困難,從而導(dǎo)致整個(gè)系統(tǒng)的可靠性和可維護(hù)性比較差。
C51是針對(duì)8051系列單片機(jī)開發(fā)的高級(jí)語言。它與標(biāo)準(zhǔn)的C語言基本一致,但根據(jù)8051單片機(jī)的硬件特點(diǎn)作了少量的擴(kuò)展和重新定義。例如,C51中定義的庫函數(shù)和標(biāo)準(zhǔn)C語言定義的庫函數(shù)不同,標(biāo)準(zhǔn)的C語言定義的庫函數(shù)是按通用微型計(jì)算機(jī)來定義的,而C51中的庫函數(shù)是按MCS-51單片機(jī)相應(yīng)情況來定義的;C51支持位變量,printf函數(shù)由串行口輸出而不是由屏幕輸出,且不同廠家的單片機(jī)為描述其硬件的差異需要使用特定的頭文件;C51與標(biāo)準(zhǔn)C在函數(shù)使用方面也有一定的區(qū)別,C51中有專門的中斷函數(shù)等。
C51主要有以下特點(diǎn):
(1)語言簡潔、緊湊,使用方便、靈活;
(2)運(yùn)算符極其豐富;
(3)生產(chǎn)的目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高;
(4)C51程序由若干函數(shù)組成,具有良好的模塊化結(jié)構(gòu),便于改進(jìn)和擴(kuò)充;
(5)有豐富的庫函數(shù),可大大減少用戶的編程量,顯著縮短編程與調(diào)試時(shí)間,大大提高軟件開發(fā)效率;
(6)可以直接對(duì)硬件進(jìn)行操作;
(7)程序具有良好的可讀性和可維護(hù)性。
單片機(jī)C51語言繼承了C語言的特點(diǎn),其程序結(jié)構(gòu)與一般C語言結(jié)構(gòu)沒有差別。C51源程序文件擴(kuò)展名為“.c”。C51程序和標(biāo)準(zhǔn)C程序結(jié)構(gòu)相同,采用函數(shù)結(jié)構(gòu)。每個(gè)C51程序由一個(gè)或多個(gè)函數(shù)組成,在這些函數(shù)中至少應(yīng)包含一個(gè)主函數(shù)main(),也可以包含一個(gè)main()函數(shù)和若干個(gè)其他的功能函數(shù)。程序的執(zhí)行總是從main()函數(shù)開始的,當(dāng)主函數(shù)所有語句執(zhí)行完畢時(shí),程序執(zhí)行完畢。
程序的開始部分一般是預(yù)處理命令、函數(shù)說明和變量定義等。
一個(gè)C51語言源程序是由一個(gè)或若干個(gè)函數(shù)組成的,每一個(gè)函數(shù)完成相對(duì)獨(dú)立的功能。每個(gè)C51程序都必須有(且僅有)一個(gè)主函數(shù)main(),程序的執(zhí)行總是從主函數(shù)開始,再調(diào)用其他函數(shù)后返回主函數(shù)main(),不管函數(shù)的排列順序如何,最后在主函數(shù)中結(jié)束整個(gè)程序。
一個(gè)函數(shù)由兩部分組成:函數(shù)定義和函數(shù)體。
函數(shù)定義部分包括函數(shù)名、函數(shù)類型、函數(shù)屬性、函數(shù)參數(shù)(形式參數(shù))名、參數(shù)類型等。對(duì)于main()函數(shù)來說,main是函數(shù)名,函數(shù)名前面的void說明函數(shù)類型(空類型,表
示沒有返回值),函數(shù)名后面必須跟一對(duì)圓括號(hào),里面是函數(shù)的形式參數(shù)定義,如main()表示該函數(shù)沒有形式參數(shù)。
main()函數(shù)后面一對(duì)大括號(hào)內(nèi)的部分稱為函數(shù)體,函數(shù)體由定義數(shù)據(jù)類型的說明部分和實(shí)現(xiàn)函數(shù)功能的執(zhí)行部分組成。
C51語言程序中可以有一些專用的預(yù)處理命令,例如上述源程序中的“#include<reg51.h>”,預(yù)處理命令通常放在源程序的最前面。
從上面的兩個(gè)源程序我們也可以看出,C51和C語言一樣,使用“;”作為語句的結(jié)束符,一條語句可以多行書寫,也可以一行書寫多條語句。
3.2標(biāo)識(shí)符和關(guān)鍵字
3.2.1標(biāo)識(shí)符標(biāo)識(shí)符常用來聲明某個(gè)對(duì)象的名稱,如變量和常量的聲明、數(shù)組和結(jié)構(gòu)的聲明、自定義函數(shù)的聲明以及數(shù)據(jù)類型的聲明等。示例如下:intsum;intkey;voiddelay();在上面的例子中,sum為整型變量的標(biāo)識(shí)符,delay為自定義函數(shù)的標(biāo)識(shí)符。
在C51語言中,標(biāo)識(shí)符可以由字母、數(shù)字(0~9)或者下劃線“_”組成,最多可支持32個(gè)字符。C51標(biāo)識(shí)符的第一個(gè)字符必須為字母或者下劃線,例如“unt”、“ch_2”等都是正確的,而“5count”則是錯(cuò)誤的標(biāo)識(shí)符。程序中對(duì)于標(biāo)識(shí)符的命名應(yīng)當(dāng)簡潔明了,含義清晰,便于閱讀理解,如用標(biāo)識(shí)符“min”表示最小值,用“TIMER1”表示定時(shí)器1等。有些編譯系統(tǒng)專用的標(biāo)識(shí)符是以下劃線開頭的,所以一般不要以下劃線開頭命名標(biāo)識(shí)符,可以將下劃線用做分段符。標(biāo)識(shí)符在命名時(shí)應(yīng)當(dāng)簡單,含義清晰,這樣有助于閱讀和理解程序。
另外,C51的標(biāo)識(shí)符區(qū)分大小寫,例如“sum”和“SUM”代表兩個(gè)不同的標(biāo)識(shí)符,使用標(biāo)識(shí)符時(shí)應(yīng)注意以下幾點(diǎn):
?在命名C51標(biāo)識(shí)符時(shí),需要能夠清楚地表達(dá)其功能含義,這樣有助于閱讀和理解源程序。
?C51的標(biāo)識(shí)符原則上可以使用下劃線開頭,但有些編譯系統(tǒng)的專用標(biāo)識(shí)符或者預(yù)定義項(xiàng)是以下劃線開頭的,因此為了程序的兼容性和可移植性,建議一般不使用下劃線開頭來命名標(biāo)識(shí)符。
?盡量不要使用過長的標(biāo)識(shí)符,以便于使用和程序理解方便。
?自定義的C51標(biāo)識(shí)符不能使用C51語言保留的關(guān)鍵字,也不能和用戶已使用的函數(shù)名或C51庫函數(shù)同名。例如“
char”是關(guān)鍵字,所以不能作為標(biāo)識(shí)符使用。
3.2.2關(guān)鍵字
關(guān)鍵字是C51語言的重要組成部分,是編程語言保留的特殊標(biāo)識(shí)符,它們具有固定名稱和含義,如int、if、for、do、while、case等。在編寫C語言源程序時(shí)一般不允許標(biāo)識(shí)符的命名與關(guān)鍵字相同。在KeilμVision中的關(guān)鍵字除了有ANSIC標(biāo)準(zhǔn)的32個(gè)關(guān)鍵字外,還根據(jù)51單片機(jī)的特點(diǎn)擴(kuò)展了相關(guān)的關(guān)鍵字。ANSIC標(biāo)準(zhǔn)的關(guān)鍵字及其擴(kuò)展關(guān)鍵字分別如表3-1和表3-2所示。在C51語言程序設(shè)計(jì)中,用戶自定義的標(biāo)識(shí)符不能和這些關(guān)鍵字沖突,否則無法通過編譯。
3.3數(shù)據(jù)類型與運(yùn)算符
具有一定格式的數(shù)字或數(shù)值叫做數(shù)據(jù)。數(shù)據(jù)是計(jì)算機(jī)操作的對(duì)象,無論使用何種語言、算法進(jìn)行程序設(shè)計(jì),最終在計(jì)算機(jī)中運(yùn)行的都是數(shù)據(jù)流,任何程序設(shè)計(jì)都離不開對(duì)于數(shù)據(jù)的處理。數(shù)據(jù)的不同存儲(chǔ)格式稱為數(shù)據(jù)類型,數(shù)據(jù)按一定的數(shù)據(jù)類型進(jìn)行排列、組合、架構(gòu)則稱為數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)在計(jì)算機(jī)內(nèi)存中的存放情況由數(shù)據(jù)結(jié)構(gòu)決定。
3.3.1數(shù)據(jù)類型
C語言的數(shù)據(jù)結(jié)構(gòu)是以數(shù)據(jù)類型體現(xiàn)的,數(shù)據(jù)類型可分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型,復(fù)雜數(shù)據(jù)類型由基本數(shù)據(jù)類型構(gòu)造而成。
C語言數(shù)據(jù)類型包括:基本類型、構(gòu)造類型、指針類型以及空類型等。基本類型有位(bit)、字符(char)、整型(int)、短整型(short)、長整型(1ong)、浮點(diǎn)型(float)以及雙精度浮點(diǎn)型(double)等;構(gòu)造類型包括數(shù)組(array)、結(jié)構(gòu)體(struct)、共用體(union)以及枚舉類型(enum)等。
C語言中的基本數(shù)據(jù)類型有char、int、short、long、float和double。對(duì)于C51編譯器來說,short型與int型相同,double型與float型相同。C51的基本數(shù)據(jù)類型如表3-3所示。
分別說明如下:
(1)char:字符類型,通常用于定義處理字符數(shù)據(jù)的變量或常量,有signedchar和unsignedchar之分,默認(rèn)為signedchar。對(duì)于signedchar型數(shù)據(jù),其字節(jié)中的最高位表示該數(shù)據(jù)的符號(hào),“0”表示正數(shù),“1”表示負(fù)數(shù),負(fù)數(shù)用補(bǔ)碼表示,所能表示的數(shù)值范圍是-128~127;unsignedchar型數(shù)據(jù)是無符號(hào)字符型數(shù)據(jù),其字節(jié)中的所有位均用來表示數(shù)據(jù)的數(shù)值,所表示的數(shù)值范圍是0~255。
(2)int:整型,長度為兩個(gè)字節(jié),用于存放一個(gè)雙字節(jié)數(shù)據(jù)。int型分有符號(hào)整型數(shù)signedint和無符號(hào)整型數(shù)unsignedint,默認(rèn)為signedint類型。signedint表示的數(shù)值范圍是-32768~+32767,字節(jié)中最高位表示數(shù)據(jù)的符號(hào),“0”表示正數(shù),“1”表示負(fù)數(shù)。unsignedint表示的數(shù)值范圍是0~65535。
(3)long:長整型,有signedlong和unsignedlong之分,默認(rèn)值為signedlong。它們的長度均為四個(gè)字節(jié)。singedlong是有符號(hào)的長整型數(shù)據(jù),字節(jié)中的最高位表示數(shù)據(jù)的符號(hào),“0”表示正數(shù),“1”表示負(fù)數(shù),數(shù)值的表示范圍是-2147483648~2147483647;unsignedlong是無符號(hào)長整型數(shù)據(jù),數(shù)值的表示范圍是0~4294967295。
(4)float:浮點(diǎn)型,是符合IEEE754標(biāo)準(zhǔn)的單精度浮點(diǎn)型數(shù)據(jù),在十進(jìn)制中具有7位有效數(shù)字。float型數(shù)據(jù)占用四個(gè)字節(jié)(2位二進(jìn)制數(shù))。需要指出的是,對(duì)于浮點(diǎn)型數(shù)據(jù),除了有正常數(shù)值之外,還可能出現(xiàn)非正常數(shù)值。
(5)*:指針型,不同于以上四種基本數(shù)據(jù)類型,它本身是一個(gè)變量,在這個(gè)變量中存放的不是一般的數(shù)據(jù)而是指向另一個(gè)數(shù)據(jù)的地址。指針變量也要占據(jù)一定的內(nèi)存單元,在C51中指針變量的長度一般為1~3個(gè)字節(jié)。指針變量也具有類型,其表示方法是在指針符號(hào)“*”的前面冠以數(shù)據(jù)類型符號(hào)。如“char*point1”表示point1是一個(gè)字符型的指針變
量;“float*point2”表示point2是一個(gè)浮點(diǎn)型的指針變量。指針變量的類型表示該指針?biāo)赶虻刂分袛?shù)據(jù)的類型。使用指針型變量可以方便地對(duì)8051單片機(jī)的各部分物理地址直
接進(jìn)行操作。
(6)bit:位標(biāo)量,是C51編譯器的一種擴(kuò)充數(shù)據(jù)類型,利用它可定義一個(gè)位標(biāo)量,但不能定義位指針,也不能定義位數(shù)組。它的值是一個(gè)二進(jìn)制位,不是0就是1,類似于一些高級(jí)語言中的Boolean類型中的True和False。
(7)sfr:特殊功能寄存器,也是一種擴(kuò)充數(shù)據(jù)類型,占用一個(gè)內(nèi)存單元,值域?yàn)?~255。利用它能訪問51單片機(jī)內(nèi)部的所有特殊功能寄存器。如用“sfrP1=0x90”定義P1為P1端口在片內(nèi)的寄存器,在后面的語句中用P1=255(對(duì)P1端口的所有引腳置高電平)之類的語句來操作特殊功能寄存器。
(8)sfr16:16位特殊功能寄存器,占用兩個(gè)內(nèi)存單元,值域?yàn)?~65535。sfr16和sfr一樣用于操作特殊功能寄存器,所不同的是它用于操作占兩個(gè)字節(jié)的寄存器,如定時(shí)器T0
和T1。
(9)sbit:可尋址位,同樣是單片機(jī)C語言中的一種擴(kuò)充數(shù)據(jù)類型。利用它能訪問芯片內(nèi)部的RAM中的可尋址位或特殊功能寄存器中的可尋址位。
在C51語言程序的表達(dá)式或變量賦值運(yùn)算中,有時(shí)會(huì)出現(xiàn)運(yùn)算對(duì)象的數(shù)據(jù)類型不一致的情況,C語言允許任何標(biāo)準(zhǔn)數(shù)據(jù)類型之間的隱式轉(zhuǎn)換。隱式轉(zhuǎn)換按以下優(yōu)先級(jí)別自動(dòng)進(jìn)行:
其中,箭頭方向僅表示數(shù)據(jù)類型級(jí)別的高低,轉(zhuǎn)換時(shí)由低向高進(jìn)行,而不是數(shù)據(jù)轉(zhuǎn)換時(shí)的順序。例如,將一個(gè)bit型變量賦給一個(gè)int型變量時(shí),直接把bit型變量值轉(zhuǎn)換成int型變
量值并完成賦值運(yùn)算。一般來說,如果有幾個(gè)不同類型的數(shù)據(jù)同時(shí)參加運(yùn)算,先將低級(jí)別類型的數(shù)據(jù)轉(zhuǎn)換成高級(jí)別類型,再做運(yùn)算處理,并且運(yùn)算結(jié)果為高級(jí)別類型數(shù)據(jù)。C語言除了能對(duì)數(shù)據(jù)類型做自動(dòng)的隱式轉(zhuǎn)換之外,還可以采用強(qiáng)制類型轉(zhuǎn)換符“()”對(duì)數(shù)據(jù)類型做顯式轉(zhuǎn)換。
強(qiáng)制類型轉(zhuǎn)換需要使用強(qiáng)制類型轉(zhuǎn)換運(yùn)算符,其形式為
(類型名)(表達(dá)式);
例如,“(double)a;”表示將a強(qiáng)制轉(zhuǎn)換成double類型。
3.3.2常量和變量
常量是在程序運(yùn)行過程中不能改變值的量,而變量是可以在程序運(yùn)行過程中不斷變化的量。變量的定義可以使用所有C51編譯器支持的數(shù)據(jù)類型,而常量的數(shù)據(jù)類型只有整型、浮點(diǎn)型、字符型、字符串型和位標(biāo)量。
1.常量
常量是指在程序執(zhí)行過程中其值不能改變的量,如固定的數(shù)據(jù)表、字庫等。C51支持整型常量、浮點(diǎn)型常量、字符型常量和字符串型常量。
1)整型常量
C51中整型常量可以表示成以下幾種形式:
(1)十進(jìn)制整數(shù),如120、-78、0等。
(2)十六進(jìn)制整數(shù),以0x開頭,如0x11表示十六進(jìn)制數(shù)11H。
(3)長整數(shù)。在C51中當(dāng)一個(gè)整數(shù)的值達(dá)到長整型的范圍時(shí),該數(shù)按長整型存放,在存儲(chǔ)器中占四個(gè)字節(jié)。另外,如在一個(gè)整數(shù)后面加一個(gè)字母L,則這個(gè)數(shù)在存儲(chǔ)器中也按長整型存放,如123L在存儲(chǔ)器中占四個(gè)字節(jié)。
2)浮點(diǎn)型常量
浮點(diǎn)型常量也即實(shí)型常數(shù),有十進(jìn)制和指數(shù)兩種表示形式。
十進(jìn)制表示形式又稱定點(diǎn)表示形式,由數(shù)字和小數(shù)點(diǎn)組成,如0.123、34.645等都是十進(jìn)制數(shù)表示形式的浮點(diǎn)型常量。
指數(shù)表示形式為
[±]數(shù)字[.數(shù)字]e[±]數(shù)字
例如,523.658e-3、-6.324e2等都是指數(shù)形式的浮點(diǎn)型常量。
3)字符型常量
字符型常量是加單引號(hào)的字符,如'b'、'3'、'M'等??梢允强娠@示的ASCII字符,也可以是不可顯示的控制字符。對(duì)不可顯示的控制字符須在前面加上反斜杠“\”組成轉(zhuǎn)義字符。利用它可以完成一些特殊功能和輸出時(shí)的格式控制。常用的轉(zhuǎn)義字符如表3-4所示。
4)字符串型常量
字符串型常量由雙引號(hào)括起的字符組成,如″LED″、″76″、″hello″等。字符串常量與字符常量是不一樣的,一個(gè)字符常量在計(jì)算機(jī)內(nèi)只用一個(gè)字節(jié)存放,而一個(gè)字符串常量在內(nèi)存中存放時(shí)不僅雙引號(hào)內(nèi)的字符一個(gè)占一個(gè)字節(jié),而且系統(tǒng)會(huì)自動(dòng)地在后面加一個(gè)轉(zhuǎn)義字符“\0”作為字符串結(jié)束符。因此不要將字符常量和字符串常量混淆,如字符常量'A'和字符串常量″A″是不一樣的。
2.變量
編寫程序時(shí),常常需要將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,方便后面使用或者修改這個(gè)數(shù)據(jù)的值。因此,需要引入變量的概念。在程序運(yùn)行過程中,其值可以被改變的量稱為變量。變量有以下三個(gè)要素。
?變量名:每個(gè)變量都必須有一個(gè)名字,即變量名。變量的命名規(guī)則與用戶自定義標(biāo)識(shí)符的命名規(guī)則相同。
?變量值:在程序運(yùn)行過程中,變量值存儲(chǔ)在內(nèi)存中;不同類型的變量占用的內(nèi)存單元(字節(jié))數(shù)不同。在程序中,通過變量名來引用變量值。
?變量的地址:即變量在內(nèi)存中存放其值的起始單元地址。
在C51中,使用變量前必須對(duì)變量進(jìn)行定義,指出變量的數(shù)據(jù)類型和存儲(chǔ)模式,以便編譯系統(tǒng)為它分配相應(yīng)的存儲(chǔ)單元。定義的格式如下:
[存儲(chǔ)種類]數(shù)據(jù)類型[存儲(chǔ)器類型]變量名表
在定義格式中除了數(shù)據(jù)類型和變量名表是必要的,其他都是可選項(xiàng)。
(1)存儲(chǔ)種類有四種:自動(dòng)(auto)、外部(extern)、靜態(tài)(static)和寄存器(register),缺省類型為自動(dòng)(auto)。
(2)數(shù)據(jù)類型說明符:指明變量的數(shù)據(jù)類型。指明變量在存儲(chǔ)器中占用的字節(jié)數(shù);數(shù)據(jù)類型可以是基本數(shù)據(jù)類型說明符,也可以是組合數(shù)據(jù)類型說明符,還可以是用typedef或#define定義的類型別名。
在C51中,為了增加程序的可讀性,允許用戶為系統(tǒng)固有的數(shù)據(jù)類型說明符用typedef或#define起別名,格式如下:
typedefC51固有的數(shù)據(jù)類型說明符別名;
或
#define別名C51固有的數(shù)據(jù)類型說明符;
定義別名后,就可以用別名代替數(shù)據(jù)類型說明符對(duì)變量進(jìn)行定義了。別名可以用大寫字母,也可以用小寫字母。如:
#defineucharunsignedchar
這樣,在編程中,就可以用uchar代替unsignedchar。
(3)存儲(chǔ)器類型:指定義變量時(shí),根據(jù)51單片機(jī)存儲(chǔ)器的特點(diǎn),指明該變量所處的單片機(jī)的內(nèi)存空間。
C51單片機(jī)的存儲(chǔ)器主要有:片內(nèi)數(shù)據(jù)存儲(chǔ)器、特殊功能寄存器、片外數(shù)據(jù)存儲(chǔ)器、片內(nèi)程序存儲(chǔ)器和片外程序存儲(chǔ)器,如表3-5所示。
使用匯編指令訪問時(shí),依據(jù)不同的指令和不同的尋址方式即可區(qū)分存儲(chǔ)器類型。在C51中,則要通過定義存儲(chǔ)器類型來加以說明。
C51編譯器支持MCS51單片機(jī)的硬件結(jié)構(gòu),可完全訪問MCS51硬件系統(tǒng)的所有部分。
編譯器通過將變量或者常量定義成不同的存儲(chǔ)類型(
data、bdata、idata、pdata、xdata、code)的方法,將它們定位在不同的存儲(chǔ)區(qū)中。
(4)變量名表格式:
變量名1[=初值],變量名2[=初值],...
在C51中,規(guī)定變量名可以由字母、數(shù)字和下劃線三種字符組成,且第一位必須為字母或下劃線。
變量名有兩種:普通變量名和指針變量名。指針變量名前面要帶“*”號(hào)。
3.3.3運(yùn)算符
運(yùn)算符就是完成某種特定運(yùn)算的符號(hào)。運(yùn)算符按其表達(dá)式中與運(yùn)算符的關(guān)系可分為單目運(yùn)算符、雙目運(yùn)算符和三目運(yùn)算符。單目指只有一個(gè)運(yùn)算對(duì)象,雙目有兩個(gè)運(yùn)算對(duì)象,三目則有三個(gè)運(yùn)算對(duì)象。由運(yùn)算符及運(yùn)算對(duì)象所組成的具有特定含義的式子稱為表達(dá)式。
1.賦值運(yùn)算符
賦值運(yùn)算符只有一個(gè),即“=”。
在C中,它的功能是給變量賦值,如x=10。
賦值表達(dá)式后面加“;”號(hào)就構(gòu)成了一個(gè)賦值表達(dá)式語句。賦值運(yùn)算符是右結(jié)合性,且優(yōu)先級(jí)最低。例如:
a=(b=2)+(c=3);
該表達(dá)式的值為5,變量a的值為5。
在賦值運(yùn)算中,當(dāng)“=”兩側(cè)的類型不一致時(shí),要將其轉(zhuǎn)換成同一數(shù)據(jù)類型。
2.算術(shù)運(yùn)算符
C51中的算術(shù)運(yùn)算符如下:
+:加或取正值運(yùn)算符;
-:減或取負(fù)值運(yùn)算符;
*:乘運(yùn)算符;
/:除運(yùn)算符;
%:模(取余)運(yùn)算符。
這些運(yùn)算符中加、減、乘、除為雙目運(yùn)算符,它們要求有兩個(gè)運(yùn)算對(duì)象。例如:9%4=1,即9除以4的余數(shù)是1。
3.自增自減運(yùn)算符
自增運(yùn)算符為“++”;自減運(yùn)算符為“--”。
自增自減運(yùn)算符的作用是使變量值自動(dòng)加1或減1。自增自減運(yùn)算符可用在操作數(shù)之前,也可放在其后。例如,“
x=x+1”既可以寫成“++x”,也可寫成“x++”,其運(yùn)算結(jié)果完全相同。但在表達(dá)式中這兩種用法是有區(qū)別的。
++i,--i:“運(yùn)算符在前,先運(yùn)算后使用”,即在使用i之前,先使i值加(減)1;
i++,i--:“運(yùn)算符在后,先使用后運(yùn)算”,即在使用i之后,再使i值加(減)1。
例如:若i值原來為4,則對(duì)于“j=++i;”語句,j值為5,i值為5;對(duì)于“j=i++;”語句,j值為4,i值為5。
一般來說,用自增和自減操作生成的程序代碼比等價(jià)的賦值語句生成的代碼運(yùn)行的速度更快。
4.關(guān)系運(yùn)算符
C51中有6種關(guān)系運(yùn)算符:
>:大于;
<:小于;
>=:大于等于;
<=:小于等于;
==:測(cè)試等于;
!=:測(cè)試不等于。
關(guān)系和邏輯運(yùn)算符的優(yōu)先級(jí)比算術(shù)運(yùn)算符低,例如表達(dá)式“10>x+12”的計(jì)算,應(yīng)看做是“10>(x+12)”。
5.邏輯運(yùn)算符
C51中的邏輯運(yùn)算符有:
&&:邏輯與;
||:邏輯或;
!:邏輯非。
具體用法如下:
邏輯與:條件式1&&條件式2;
邏輯或:條件式1||條件式2;
邏輯非:!條件式。
6.位運(yùn)算符
位運(yùn)算符的作用是按位對(duì)變量進(jìn)行運(yùn)算,但并不改變參與運(yùn)算的變量的值。位運(yùn)算符不能用來對(duì)浮點(diǎn)型數(shù)據(jù)進(jìn)行操作。位運(yùn)算一般的表達(dá)形式如下:
變量1位運(yùn)算符變量2
C51中共有6種位運(yùn)算符(優(yōu)先級(jí)從上往下遞減):
&:按位與;
|:按位或;
^:按位異或;
~:按位取反;
<<:左移;
>>:右移。
7.復(fù)合運(yùn)算符
復(fù)合運(yùn)算符就是在賦值運(yùn)算符“=”的前面加上其他運(yùn)算符。以下是C51語言中的復(fù)合賦值運(yùn)算符:
+=:加法賦值;
>>=:右移位賦值;
-=:減法賦值;
&=:邏輯與賦值;
*=:乘法賦值;
|=:邏輯或賦值;
/=:除法賦值;
^=:邏輯異或賦值;
%=:取模賦值;
~=:邏輯非賦值;
<<=:左移位賦值。
其含義就是變量與表達(dá)式先進(jìn)行運(yùn)算符所要求的運(yùn)算,再把運(yùn)算結(jié)果賦值給參與運(yùn)算的變量。其實(shí)這是C語言中簡化程序的一種方法,凡是二目運(yùn)算都可以用復(fù)合賦值運(yùn)算符去簡化表達(dá)。例如:
8.對(duì)指針操作的運(yùn)算符
對(duì)指針操作的運(yùn)算符只有一個(gè),即“&”,其又能用于按位與,此時(shí)“&”的兩邊必須有操作對(duì)象。還可作為指針變量的標(biāo)志,但此時(shí)一定出現(xiàn)在對(duì)指針定義中。
9.條件運(yùn)算符
C51中的條件運(yùn)算符為“?:”。
條件運(yùn)算符是C51語言中唯一的一個(gè)三目運(yùn)算符,它要求有三個(gè)運(yùn)算對(duì)象,用它可以將三個(gè)表達(dá)式連接在一起構(gòu)成一個(gè)條件表達(dá)式。條件表達(dá)式的一般格式為
邏輯表達(dá)式?表達(dá)式1:表達(dá)式2
邏輯表達(dá)式?表達(dá)式1:表達(dá)式2
其功能是先計(jì)算邏輯表達(dá)式的值,當(dāng)邏輯表達(dá)式的值為真(非0值)時(shí),將計(jì)算的表達(dá)式1的值作為整個(gè)條件表達(dá)式的值;當(dāng)邏輯表達(dá)式的值為假(0值)時(shí),將計(jì)算的表達(dá)式2的值
作為整個(gè)條件表達(dá)式的值。
例如,條件表達(dá)式“max=(a>b)?a:b”的執(zhí)行結(jié)果是將a和b中較大的數(shù)賦值給變量max。
10.強(qiáng)制轉(zhuǎn)換運(yùn)算符
當(dāng)參與運(yùn)算的數(shù)據(jù)的類型不同時(shí),先轉(zhuǎn)換成同一數(shù)據(jù)類型,再進(jìn)行運(yùn)算。數(shù)據(jù)類型的轉(zhuǎn)換方式有兩種:一種是自動(dòng)類型轉(zhuǎn)換:另一種是強(qiáng)制轉(zhuǎn)換。
自動(dòng)類型轉(zhuǎn)換是在對(duì)程序進(jìn)行編譯時(shí)由編譯器自動(dòng)處理的。自動(dòng)類型轉(zhuǎn)換的基本規(guī)則是轉(zhuǎn)換后計(jì)算精度不降低,所以當(dāng)char、int、unsigned、long、double類型的數(shù)據(jù)同時(shí)存在時(shí),其轉(zhuǎn)換關(guān)系為char→int→unsigned→long→double。例如,當(dāng)char型數(shù)據(jù)與int型數(shù)據(jù)共存時(shí),先將char型轉(zhuǎn)化為int型再計(jì)算。
強(qiáng)制轉(zhuǎn)換是通過強(qiáng)制類型轉(zhuǎn)換運(yùn)算符“()”進(jìn)行的,其作用是將一個(gè)表達(dá)式轉(zhuǎn)化為所需類型。其一般形式為
(類型標(biāo)識(shí)符)(表達(dá)式)
例如,“int(x+y)”將x+y的結(jié)果強(qiáng)制轉(zhuǎn)換為整型。
任務(wù)3-1不同數(shù)據(jù)類型控制LED閃爍
任務(wù)目的分別采用兩種不同的數(shù)據(jù)類型,即整型和字符型設(shè)計(jì)延時(shí)函數(shù),用同樣大小數(shù)字來控制延時(shí)時(shí)間,實(shí)現(xiàn)LED的閃爍,通過觀察閃爍現(xiàn)象來理解不同數(shù)據(jù)類型的區(qū)別。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
(1)分別采用無符號(hào)整型和無符號(hào)字符型數(shù)據(jù)類型來控制延時(shí)函數(shù)的時(shí)間。unsignedchar類型用單字節(jié)來表示數(shù)值,數(shù)值范圍是0~255。unsignedint類型是用雙字節(jié)來表示
數(shù)值的,數(shù)值范圍是0~65535。
(2)對(duì)不同類型的變量設(shè)置相同的延時(shí)控制參數(shù),使得兩燈相互交替閃爍,觀察不同數(shù)據(jù)類型控制的LED閃爍的區(qū)別。任務(wù)電路Proteus原理圖如圖3-1所示,當(dāng)P1.0或P1.1輸出為0時(shí),對(duì)應(yīng)發(fā)光二極管D1或D2點(diǎn)亮。當(dāng)P1.0或P1.1輸出為1時(shí),對(duì)應(yīng)發(fā)光二極管D1或D2熄滅。圖3-1不同數(shù)據(jù)類型實(shí)現(xiàn)LED閃爍電路圖
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-1所示的電路原理圖,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-2所示。圖3-2不同數(shù)據(jù)類型實(shí)現(xiàn)LED閃爍仿真圖
任務(wù)結(jié)論
采用整型和字符型同樣大小數(shù)值的延時(shí)時(shí)間控制LED的閃爍,通過仿真和實(shí)際電路板運(yùn)行現(xiàn)象觀察,很明顯D1點(diǎn)亮和熄滅的時(shí)間長于D2點(diǎn)亮和熄滅的時(shí)間。由此看出不同
數(shù)據(jù)類型在數(shù)據(jù)存儲(chǔ)及處理時(shí)的區(qū)別。
任務(wù)3-2數(shù)據(jù)運(yùn)算的LED顯示
任務(wù)目的利用51單片機(jī)編程實(shí)現(xiàn)“60+43”和“6043”兩道加法和減法運(yùn)算,并將運(yùn)算結(jié)果分別采用P1口外接的8個(gè)LED以二進(jìn)制的方式顯示。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
定義兩個(gè)無符號(hào)字符型變量a和b,并將其分別賦值為60和43,然后直接將n+m和n-m的結(jié)果分別送入寄存器P1。任務(wù)電路Proteus原理圖如圖3-3所示,當(dāng)P0口或P1口引腳輸出為0時(shí),對(duì)應(yīng)發(fā)光二極管點(diǎn)亮;當(dāng)P1口引腳輸出為1時(shí),對(duì)應(yīng)發(fā)光二極管熄滅。根據(jù)P0口或P1口分別所接的8個(gè)LED的亮滅狀態(tài)可以看出P0口或P1口輸出的高低電平組合,進(jìn)一步可得出其二進(jìn)制組合信息,從而驗(yàn)證相應(yīng)算數(shù)運(yùn)算的正確性。圖3-3數(shù)據(jù)運(yùn)算的LED實(shí)現(xiàn)
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-3所示的電路,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-4所示。圖3-4數(shù)據(jù)運(yùn)算的LED實(shí)現(xiàn)仿真效果圖
任務(wù)結(jié)論
通過仿真圖和開發(fā)板的指示燈可以看到P0口和P1口外接的LED的亮滅狀態(tài)實(shí)現(xiàn)了“60+43”和“60-43”兩道加法和減法運(yùn)算結(jié)果與預(yù)期結(jié)果相同,驗(yàn)證了51單片機(jī)的加減算術(shù)運(yùn)算。
3.4C語言的語句
一個(gè)C程序是由若干語句組成的,每個(gè)語句以分號(hào)作為結(jié)束符。C語言的語句可以分為5類,即控制語句、表達(dá)式語句、函數(shù)調(diào)用語句、空語句和復(fù)合語句。其中,除了控制語句外,其余4類都屬于順序執(zhí)行語句。
3.4.1順序執(zhí)行語句
1.表達(dá)式語句
表達(dá)式語句由表達(dá)式加上分號(hào)組成,最常見的就是賦值語句,由一個(gè)賦值表達(dá)式后面跟一個(gè)分號(hào)組成。例如:
n=8;/*將8賦值給變量n*/
x=5*x;/*將變量x的值乘以5的結(jié)果賦給變量x*/
事實(shí)上,任何表達(dá)式都可以加上分號(hào)成為語句,例如,經(jīng)常在程序中出現(xiàn)如下的語句:
i++;/*使i變量的值加1*/
需要注意的是,有些寫法雖然是合法的,但是沒有保留計(jì)算結(jié)果,因而沒有實(shí)際的意義。例如:
b-3;
i++-6;
2.函數(shù)調(diào)用語句
由函數(shù)調(diào)用加上分號(hào)組成,例如:
printf(″Hello″);/*調(diào)用庫函數(shù),輸出字符串*/
函數(shù)是一段程序,這段程序可能存在于函數(shù)庫中,也可能是由用戶自己定義的,當(dāng)調(diào)用函數(shù)時(shí)會(huì)轉(zhuǎn)到該段程序執(zhí)行。但函數(shù)調(diào)用語句與前后語句之間的關(guān)系是順序執(zhí)行的。
3.空語句
只有分號(hào)組成的語句稱為空語句。在程序中,如果沒有什么操作需要進(jìn)行,但從語句的結(jié)構(gòu)上來說必須有一個(gè)語句時(shí),可以書寫一個(gè)空語句。
4.復(fù)合語句
把多個(gè)語句用大括號(hào)括起來組成的一個(gè)語句稱為復(fù)合語句。例如:
{
a=3+9j
b=15;
c=Sqrt(a*a+b*b);
}
復(fù)合語句內(nèi)的各條語句都必須以分號(hào)結(jié)尾,在大括號(hào)外不能加分號(hào)。
3.4.2控制語句
控制語句用于控制程序流程,實(shí)現(xiàn)程序執(zhí)行流程的轉(zhuǎn)移??刂普Z句包括以下9種:
if()...else...:條件語句;
switch:多分支選擇語句;
for()...
:循環(huán)語句;
do...while():循環(huán)語句;
while():循環(huán)語句;
goto:無條件轉(zhuǎn)向語句;
continue:結(jié)束本次循環(huán)語句;
return:從函數(shù)返回語句;
break:終止執(zhí)行switch或循環(huán)語句。
上述語句中的“()”表示其中是一個(gè)判定條件;“...”表示內(nèi)嵌的語句。
1.條件語句
條件語句又被稱為分支語句,也有人稱之為判斷語句,其關(guān)鍵字由if構(gòu)成,這在眾多的高級(jí)語言中都是基本相同的。C語言提供了三種形式的條件語句:
(1)if(條件表達(dá)式)語句
當(dāng)條件表達(dá)式的結(jié)果為真時(shí),就執(zhí)行語句,不然就跳過。如“if(a==b)a++;”表示當(dāng)a等于b時(shí),a加1。
(2)if(條件表達(dá)式)語句1
else語句2當(dāng)條件表達(dá)式成立時(shí),執(zhí)行語句1,否則執(zhí)行語句2。例如:
if(a==b)
a++;
else
a--;
表示當(dāng)a等于b時(shí),a加1,否則a減1。
(3)if(條件表達(dá)式1)語句1
elseif(條件表達(dá)式2)語句2
elseif(條件表達(dá)式3)語句3
elseif(條件表達(dá)式m)語句n
else語句m
這是由ifelse語句組成的嵌套,用來實(shí)現(xiàn)多方向條件分支,使用時(shí)應(yīng)注意if和else要配對(duì)使用,少了一個(gè)就會(huì)語法出錯(cuò),且else總是與最臨近的if相配對(duì)。一般條件語句只會(huì)用做單一條件或少數(shù)量的分支,分支較多時(shí)則會(huì)用到下面將介紹的開關(guān)語句。
2.分支語句
用多個(gè)條件語句能實(shí)現(xiàn)多方向條件分支,但是使用過多的條件語句實(shí)現(xiàn)多方向分支會(huì)使條件語句嵌套過多,程序冗長,不宜讀。使用分支語句不但能達(dá)到處理多分支選擇的目
的,而且能使程序結(jié)構(gòu)清晰。
分支語句格式如下:
switch(表達(dá)式)
{
case常量表達(dá)式1:語句1;break;
case常量表達(dá)式2:語句2;break;
case常量表達(dá)式3:語句3;break;
case常量表達(dá)式n:語句n;break;
default:語句;
}
運(yùn)行中,switch后面的表達(dá)式的值將會(huì)作為條件,與case后面的各個(gè)常量表達(dá)式的值相對(duì)比,如果相等則執(zhí)行case后面的語句,再執(zhí)行break(間斷語句)語句,以跳出switch語句。如果case后沒有和條件相等的值時(shí)就執(zhí)行default后的語句。若在沒有符合的條件時(shí)要求不做任何處理,則可以不寫default語句。
3.for語句
采用for語句構(gòu)成循環(huán)結(jié)構(gòu)的一般形式如下:
for([初值設(shè)定表達(dá)式];[循環(huán)條件表達(dá)式];
[更新表達(dá)式])循環(huán)體語句;
for語句的執(zhí)行過程是:先計(jì)算出初值設(shè)定表達(dá)式的值作為循環(huán)控制變量的初值,再檢查循環(huán)條件表達(dá)式的結(jié)果,當(dāng)滿足循環(huán)條件時(shí)就執(zhí)行循環(huán)體語句并計(jì)算更新表達(dá)式,然后根據(jù)更新表達(dá)式的計(jì)算結(jié)果來判斷循環(huán)條件是否滿足……一直進(jìn)行到循環(huán)條件表達(dá)式的結(jié)果為假(0值)時(shí),退出循環(huán)體。
在C語言程序的循環(huán)結(jié)構(gòu)中,for語句的使用最為靈活,它不僅可以用于循環(huán)次數(shù)已經(jīng)確定的情況,而且可以用于循環(huán)次數(shù)不確定而只給出循環(huán)結(jié)束條件的情況。另外,for語
句中的三個(gè)表達(dá)式是相互獨(dú)立的,并不一定要求三個(gè)表達(dá)式之間有依賴關(guān)系。并且for語句中的三個(gè)表達(dá)式都可能缺省,但無論缺省哪一個(gè)表達(dá)式,其中的兩個(gè)分號(hào)都不能缺省。一般不要缺省循環(huán)條件表達(dá)式,以免形成死循環(huán)。
4.do...while語句
采用do...while語句構(gòu)成循環(huán)結(jié)構(gòu)的一般形式如下:
do循環(huán)體語句while(條件表達(dá)式);
這種循環(huán)結(jié)構(gòu)的特點(diǎn)是先執(zhí)行給定的循環(huán)體語句,再檢查條件表達(dá)式的結(jié)果。當(dāng)多件表達(dá)式的值為真(非0值)時(shí),重復(fù)執(zhí)行循環(huán)體語句,直到條件表達(dá)式的值為假(0值時(shí)為止。因此,do...while語句構(gòu)成的循環(huán)結(jié)構(gòu)在任何條件下,循環(huán)體語句至少會(huì)被執(zhí)行一次。
5.while語句
采用while語句構(gòu)成循環(huán)結(jié)構(gòu)的一般形式如下:
while(條件表達(dá)式)循環(huán)體語句;
其意義為,當(dāng)條件表達(dá)式的結(jié)果為真(非0值)時(shí),程序就重復(fù)執(zhí)行后面的循環(huán)體語句,一直執(zhí)行到條件表達(dá)式的結(jié)果為假(0值)為止。這種循環(huán)結(jié)構(gòu)是先檢查條件表達(dá)式所給出
的條件,再根據(jù)檢查的結(jié)果決定是否執(zhí)行后面的語句。如果條件表達(dá)式的結(jié)果一開始就為假,則后面的語句一次也不會(huì)被執(zhí)行。這里的語句可以是復(fù)合語句。
6.goto語句
goto語句是一個(gè)無條件轉(zhuǎn)向語句,它的一般形式為
goto語句標(biāo)號(hào);
其中,語句標(biāo)號(hào)是一個(gè)帶冒號(hào)“:”的標(biāo)識(shí)符。將goto語句和if語句一起使用,可以構(gòu)成一個(gè)循環(huán)結(jié)構(gòu)。但更常見的是在C語言程序中采用goto語句來跳出多重循環(huán)。需要注意的是,只能用goto語句從內(nèi)層循環(huán)跳到外層循環(huán),而不允許從外層循環(huán)跳到內(nèi)層循環(huán)。
7.continue語句
continue語句是一種中斷語句,它一般用在循環(huán)結(jié)構(gòu)中,其功能是結(jié)束本次循環(huán),即跳過循環(huán)體中下面尚未執(zhí)行的語句,把程序流程轉(zhuǎn)移到當(dāng)前循環(huán)語句的下一個(gè)循環(huán)周期,
并根據(jù)循環(huán)控制條件決定是否重復(fù)執(zhí)行該循環(huán)體。
continue語句的一般形式為
continue;
continue語句通常和條件語句一起用在由while、do...while和for語句構(gòu)成的循環(huán)結(jié)構(gòu)中。continue語句也是一種具有特殊功能的無條件轉(zhuǎn)移語句,但與break語句不同,continue語句并不跳出循環(huán)體,而只是根據(jù)循環(huán)控制條件確定是否繼續(xù)執(zhí)行循環(huán)語句。
8.return語句
return語句的一般形式為
return(表達(dá)式);
如果return語句后面帶有表達(dá)式,則要計(jì)算表達(dá)式的值,并將表達(dá)式的值作為該函數(shù)的返回值;如果不帶表達(dá)式,則被調(diào)用函數(shù)返回主調(diào)用函數(shù)時(shí),函數(shù)值不確定。一個(gè)函數(shù)的內(nèi)部可以含有多個(gè)return語句,但程序僅執(zhí)行其中的一個(gè)return語句而返回主調(diào)用函數(shù)。一個(gè)函數(shù)的內(nèi)部也可以沒有return語句,在這種情況下,當(dāng)程序執(zhí)行到最后一個(gè)界限符“}”處時(shí),就自動(dòng)返回主調(diào)用函數(shù)。
9.break語句
break語句可以跳出switch結(jié)構(gòu),使程序繼續(xù)執(zhí)行switch結(jié)構(gòu)后面的一個(gè)語句。
break語句還可以從循環(huán)體中跳出循環(huán),提前結(jié)束循環(huán)而接著執(zhí)行循環(huán)結(jié)構(gòu)下面的語句。對(duì)于多重循環(huán)的情況,break語句只能跳出它所處的那一層循環(huán),而不像goto語句可以直接從最內(nèi)層循環(huán)中跳出來。由此可見,要退出多重循環(huán)時(shí),采用goto語句比較方便。需要指出的是,break語句只能用于開關(guān)語句和循環(huán)語句之中,它是一種具有特殊功能的無條件轉(zhuǎn)移語句。另外還要注意,在進(jìn)行實(shí)際程序設(shè)計(jì)時(shí),為了保證程序具有良好的結(jié)構(gòu),應(yīng)當(dāng)盡可能地少采用goto語句,以使程序結(jié)構(gòu)清晰易讀。
任務(wù)3-3用if語句控制LED的亮滅狀態(tài)
任務(wù)目的設(shè)計(jì)一個(gè)函數(shù),采用單片機(jī)和開關(guān)配合控制LED的亮滅。一個(gè)按鍵S1接在P3.5與GND之間,另一個(gè)按鍵S2接在P3.4與GND之間,發(fā)光二極管D1接單片機(jī)P1.0引腳。按下開關(guān)S1后LED亮,按下開關(guān)S2后LED滅。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
通過單片機(jī)獲取S1和S2的開關(guān)狀態(tài),并根據(jù)開關(guān)的閉合情況來控制LED的亮滅。任務(wù)電路Proteus原理圖如圖3-5所示,由圖可知,當(dāng)開關(guān)S1或S2被按下時(shí),對(duì)應(yīng)的單片機(jī)P3.5和P3.4引腳會(huì)被拉低成低電平。通過引腳狀態(tài)來判斷按鍵是否被按下,從而控制單片機(jī)P1.0引腳輸出電平的高低狀態(tài),進(jìn)一步控制D1的亮滅。其中引腳狀態(tài)的判斷可用if語句來實(shí)現(xiàn)。圖3-5if語句控制LED亮滅閃爍
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-5所示的電路原理圖,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-6所示。圖3-6if語句控制LED亮滅閃爍仿真效果圖
任務(wù)結(jié)論
通過任務(wù)實(shí)施結(jié)果可以看出,用if語句可以對(duì)單片機(jī)引腳狀態(tài)的不同情況加以區(qū)分和判斷,從而實(shí)現(xiàn)對(duì)單片機(jī)的有效控制。
任務(wù)3-4用for語句控制LED的循環(huán)亮滅狀態(tài)
任務(wù)目的用單片機(jī)的P1口控制8個(gè)發(fā)光二極管來模擬8個(gè)信號(hào)燈。按照規(guī)律依次點(diǎn)亮每一個(gè)發(fā)光二極管并延時(shí)一段時(shí)間,以實(shí)現(xiàn)流水燈的效果。編程時(shí)使用for語句來實(shí)現(xiàn)程序的循環(huán)部分控制代碼。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
任務(wù)要求單片機(jī)控制P1口所接的8個(gè)LED,實(shí)現(xiàn)流水亮滅效果??梢酝ㄟ^單獨(dú)位控制方式實(shí)現(xiàn)LED的亮滅,但由于要控制8個(gè)燈的亮滅狀態(tài),所以編程會(huì)比較繁瑣,程序不
夠優(yōu)化。當(dāng)需要對(duì)某個(gè)I/O口的8位一起操作時(shí),一般采用整體操作的方式。在軟件設(shè)計(jì)時(shí)可以定義一個(gè)變量來給P1口賦值,賦的值不同,點(diǎn)亮的LED不同。控制好賦值的間隔
時(shí)間,即可實(shí)現(xiàn)8個(gè)LED發(fā)光二極管的流水效果。程序流程圖如圖3-7所示。圖3-78個(gè)LED循環(huán)亮滅控制程序流程圖
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-8所示電路原理圖,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-9所示。圖3-8for語句控制LED循環(huán)亮滅圖圖3-9for語句控制LED循環(huán)亮滅仿真效果圖
任務(wù)結(jié)論
通過仿真運(yùn)行圖和開發(fā)板運(yùn)行可以看到8個(gè)LED循環(huán)亮滅,說明for語句可以實(shí)現(xiàn)控制LED循環(huán)亮滅的功能。使用for語句按照一定的時(shí)間間隔循環(huán)給P1口送相應(yīng)顯示數(shù)據(jù),實(shí)現(xiàn)8燈流水功能,程序更加簡潔明了。
3.5C語言的數(shù)組
3.5.1一維數(shù)組一維數(shù)組只有一個(gè)下標(biāo),定義的形式如下:
數(shù)據(jù)類型說明符數(shù)組名[常量表達(dá)式][={初值,初值...}]各部分說明如下:(1)數(shù)據(jù)類型說明符說明了數(shù)組中各個(gè)元素存儲(chǔ)的數(shù)據(jù)的類型。(2)數(shù)組名是整個(gè)數(shù)組的標(biāo)識(shí)符,它的取名方法與變量的取名方法相同。
(3)常量表達(dá)式的取值須為整型常量,且必須用方括號(hào)“[]”括起來,用以說明該數(shù)組的長度,即該數(shù)組元素的個(gè)數(shù)。
(4)初值用于給數(shù)組元素賦初值,這部分在數(shù)組定義時(shí)屬于可選項(xiàng)。對(duì)數(shù)組元素賦值,可以在定義時(shí)賦值,也可以在定義之后賦值。在定義時(shí)賦值,后面須帶等號(hào);初值須用花括號(hào)括起來,括號(hào)內(nèi)的初值兩兩之間用逗號(hào)相隔;可以對(duì)數(shù)組的全部元素賦值,也可以只對(duì)部分元素賦值。初值為0的元素可以只用逗號(hào)占位而不寫初值0。
對(duì)數(shù)組元素的初始化可以用以下方法實(shí)現(xiàn):
(1)在定義數(shù)組時(shí)對(duì)數(shù)組元素賦以初值。例如:
inta[10]={0,1,2,3,4,5,6,7,8,9};
(2)只給一部分元素賦值。例如:
inta[10]={0,1,2,3,4};
該語句定義a數(shù)組有10個(gè)元素,但花括弧內(nèi)只提供5個(gè)初值,這表示只給前面5個(gè)元素賦初值,后5個(gè)元素值為0。
(3)如果想使一個(gè)數(shù)組中全部元素值為0,可以寫成
inta[10]={0,0,0,0,0,0,0,0,0,0};
不能寫成
inta[10]={0*10};
(4)在對(duì)全部數(shù)組元素賦初值時(shí),可以不指定數(shù)組長度。例如:
inta[5]={1,2,3,4,5};
可以寫成
inta[]={1,2,3,4,5}
3.5.2二維數(shù)組
二維數(shù)組的定義:
類型說明符數(shù)組名[整型表達(dá)式1][整型表達(dá)式2];
二維數(shù)組的元素個(gè)數(shù)=行數(shù)×列數(shù),例如:
inta[3][2];
語句定義了一個(gè)3行2列共6個(gè)數(shù)組元素的數(shù)組。
二維數(shù)組的引用格式如下:
數(shù)組名[下標(biāo)1][下標(biāo)2]
注:內(nèi)存是一維的,數(shù)組元素在存儲(chǔ)器中的存放順序按行序優(yōu)先,即“先行后列”。
二維數(shù)組初始化也是在類型說明時(shí)給各下標(biāo)變量賦以初值。二維數(shù)組可按行分段賦值,也可按行連續(xù)賦值。例如,對(duì)數(shù)組a[5][3],如果按行分段賦值可寫為
inta[5][3]={{80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85}};
如果按行連續(xù)賦值可寫為
inta[5][3]={80,75,92,61,65,71,59,63,70,85,87,90,76,77,85};
3.5.3字符數(shù)組
用來存放字符數(shù)據(jù)的數(shù)組稱為字符數(shù)組,它是C語言中常用的一種數(shù)組。字符數(shù)組中的每一個(gè)元素都用來存放一個(gè)字符,也可用字符數(shù)組來存放字符串。字符數(shù)組的定義與一
般數(shù)組相同,只是在定義時(shí)把數(shù)據(jù)類型定義為char型。例如:
charstring1[10];
charstring2[20];
這兩個(gè)語句定義了兩個(gè)字符數(shù)組,分別定義了10個(gè)元素和20個(gè)元素。
在C51中,字符數(shù)組用于存放一組字符或字符串,字符串以“\0”作為結(jié)束符,只存放一般字符的字符數(shù)組的賦值與使用和一般的數(shù)組完全相同。對(duì)于存放字符串的字符數(shù)組,
既可以對(duì)字符數(shù)組的元素逐個(gè)進(jìn)行訪問,也可以對(duì)整個(gè)數(shù)組按字符串的方式進(jìn)行處理。
任務(wù)3-5用字符型數(shù)組實(shí)現(xiàn)LED循環(huán)亮滅
任務(wù)目的采用單片機(jī)控制LED的循環(huán)亮滅狀態(tài),實(shí)現(xiàn)流水效果。把P1口8位LED的控制碼賦給一個(gè)數(shù)組,再依次引用數(shù)組元素,并送P1口顯示,通過LED觀察LED流水效果。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
定義一個(gè)一維數(shù)組用來存放8個(gè)LED的顯示數(shù)據(jù),依次為0xfe、0xfd、0xfb、0xf7、0xef、0xdf、0xbf、0x7f。通過循環(huán)將這8個(gè)數(shù)組元素按照一定時(shí)間間隔分別送至單片機(jī)P1口,即可實(shí)現(xiàn)D1至D7循環(huán)點(diǎn)亮,實(shí)現(xiàn)流水效果。
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-10所示的電路原理圖,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-11所示。圖3-10字符型數(shù)組控制LED循環(huán)亮滅電路原理圖圖3-11字符型數(shù)組控制LED循環(huán)亮滅仿真效果圖
任務(wù)結(jié)論
該程序?qū)⒁痪S數(shù)組和for語句搭配,按照一定的時(shí)間間隔循環(huán)給P1口送相應(yīng)顯示數(shù)據(jù),實(shí)現(xiàn)8燈流水效果功能,無需對(duì)送顯數(shù)據(jù)做進(jìn)一步處理,程序思路更加清晰,實(shí)現(xiàn)起來也較為方便。
3.6C語言的函數(shù)
3.6.1函數(shù)的定義函數(shù)定義的一般格式如下:函數(shù)類型函數(shù)名(形式參數(shù)表)[interruptn][usingn]形式參數(shù)說明{局部變量定義函數(shù)體(有返回值的要有return語句)}
1)函數(shù)類型
函數(shù)類型說明了函數(shù)返回值的類型。
2)函數(shù)名
函數(shù)名是用戶為自定義函數(shù)取的名字,以便調(diào)用函數(shù)時(shí)使用。
3)形式參數(shù)表
形式參數(shù)表用于列錄在主調(diào)函數(shù)與被調(diào)用函數(shù)之間進(jìn)行數(shù)據(jù)傳遞的形式參數(shù)。
4)interruptn修飾符
interruptn是C51函數(shù)中非常重要的一個(gè)修飾符,這是因?yàn)橹袛嗪瘮?shù)必須通過它進(jìn)行修飾。在C51程序設(shè)計(jì)中,若在函數(shù)定義時(shí)用了interruptn修飾符,系統(tǒng)編譯時(shí)就把對(duì)應(yīng)函數(shù)轉(zhuǎn)化為中斷函數(shù),自動(dòng)加上程序頭段和尾段,并按MCS51系統(tǒng)中斷的處理方式自動(dòng)把它安排在程序存儲(chǔ)器中的相應(yīng)位置。
該修飾符中n的取值為0~31,對(duì)應(yīng)的中斷情況如下:
0———外部中斷0;
1———定時(shí)/計(jì)數(shù)器T0;
2———外部中斷1;
3———定時(shí)/計(jì)數(shù)器T1;
4———串行口中斷;
5———定時(shí)/計(jì)數(shù)器T2;
其他值預(yù)留。
5)函數(shù)返回值
返回語句return用來回送一個(gè)數(shù)值給定義的函數(shù),從函數(shù)中退出。
返回值是通過return語句返回的。
返回值的類型如果與函數(shù)定義的類型不一致,那么返回值將被自動(dòng)轉(zhuǎn)換成函數(shù)定義的類型。
如果函數(shù)無需返回值,可以用void類型說明符指明函數(shù)無返回值。
6)usingn修飾符
修飾符usingn用于指定本函數(shù)內(nèi)部使用的工作寄存器組,其中n的取值為0~3,表示寄存器組號(hào)。
使用usingn修飾符時(shí)應(yīng)注意以下幾點(diǎn):
(1)加入usingn后,C51在編譯時(shí)自動(dòng)在函數(shù)的開始和結(jié)束處加入以下指令:
{
PUSHPSW;標(biāo)志寄存器入棧
MOVPSW,#(與寄存器組號(hào)相關(guān)的常量)
?
POPPSW;標(biāo)志寄存器出棧
}
(2)usingn修飾符不能用于有返回值的函數(shù),因?yàn)镃51函數(shù)的返回值是放在寄存器中的。如寄存器組改變了,返回值就會(huì)出錯(cuò)。
3.6.2函數(shù)的調(diào)用與聲明
與使用變量一樣,在調(diào)用一個(gè)函數(shù)之前,必須對(duì)該函數(shù)進(jìn)行聲明。函數(shù)聲明的一般格式為
[extern]函數(shù)類型函數(shù)名(形式參數(shù)列表)
函數(shù)定義時(shí)參數(shù)列表中的參數(shù)稱為形式參數(shù),簡稱形參。函數(shù)調(diào)用時(shí)所使用的替換參數(shù)是實(shí)際參數(shù),簡稱實(shí)參。定義的形參與函數(shù)調(diào)用的實(shí)參類型應(yīng)該一致,書寫順序應(yīng)該相同。
如果聲明的函數(shù)在文件內(nèi)部,則聲明時(shí)不用extern;如果聲明的函數(shù)不在文件內(nèi)部,而在另一個(gè)文件中,則聲明時(shí)須帶extern,指明使用的函數(shù)在另一個(gè)文件中。
函數(shù)調(diào)用的一般形式如下:
函數(shù)名(實(shí)參列表);
被調(diào)用的函數(shù)必須是已經(jīng)存在的函數(shù)。按照函數(shù)調(diào)用在主調(diào)函數(shù)中出現(xiàn)的位置,函數(shù)調(diào)用方式有以下三種:
(1)函數(shù)作為語句。把函數(shù)調(diào)用作為一個(gè)語句,不使用函數(shù)返回值,只是完成函數(shù)所定義的操作。例如:
refresh_led();
(2)函數(shù)作為表達(dá)式。函數(shù)調(diào)用出現(xiàn)在一個(gè)表達(dá)式中,使用函數(shù)的返回值。例如:
intk;
k=sum(a,b);
(3)函數(shù)作為一個(gè)參數(shù)。函數(shù)調(diào)用作為另一個(gè)函數(shù)的實(shí)參。例如:
intk;
k=sum(sum(a,b),c);
任務(wù)3-6用函數(shù)實(shí)現(xiàn)LED流水速度控制
任務(wù)目的設(shè)計(jì)一個(gè)函數(shù),采用單片機(jī)控制LED的流水速度,實(shí)現(xiàn)8個(gè)LED發(fā)光二極管以兩種不同的速度亮滅的流水燈效果,通過LED觀察速度切換效果。任務(wù)準(zhǔn)備設(shè)備及軟件:萬用表、計(jì)算機(jī)、KeilμVision4軟件、Proteus軟件。
任務(wù)實(shí)施
1.任務(wù)分析
單片機(jī)P1口外接8個(gè)LED,電路原理圖如圖3-12所示。其流水燈效果的流水速度由調(diào)用的軟件延時(shí)時(shí)間來控制。通過實(shí)參傳遞形成兩個(gè)不同延時(shí)長短的延時(shí)函數(shù),在實(shí)現(xiàn)流水效果時(shí)相鄰輪次調(diào)用不同的延時(shí)函數(shù),從而控制P1口所接的8個(gè)LED以兩種不同頻率切換,通過LED觀察流水頻率切換效果。
2.軟件仿真
(1)打開Keil軟件,在軟件中輸入任務(wù)程序,并對(duì)程序進(jìn)行編譯,直至沒有錯(cuò)誤,并生成相應(yīng)的hex文件。
(2)打開Proteus軟件,繪制如圖3-12所示電路原理圖,導(dǎo)入編譯后生成的hex文件,運(yùn)行程序,觀察仿真效果,如圖3-13所示。圖3-12函數(shù)實(shí)現(xiàn)LED流水速度控制的電路原理圖圖3-13函數(shù)實(shí)現(xiàn)LED流水速度控制的仿真效果圖
任務(wù)結(jié)論
單片機(jī)通過調(diào)用延時(shí)函數(shù)實(shí)現(xiàn)延時(shí)效果,給延時(shí)函數(shù)傳遞實(shí)參來控制延時(shí)的時(shí)間長短,從而控制P1口所接的8個(gè)LED以兩個(gè)頻率閃爍速度切換流水燈效果。
3.7C語言的編譯預(yù)處理
3.7.1宏定義“#define”指令宏定義的作用是用一個(gè)字符串替換另一個(gè)字符串,可以簡化程序,并且一目了然。宏定義的簡單形式是符號(hào)常量定義,復(fù)雜形式是帶參數(shù)的宏定義。
1)不帶參數(shù)的宏定義
不帶參數(shù)的宏定義又稱符號(hào)常量定義,一般格式為
#define標(biāo)識(shí)符常量表達(dá)式
其中,“標(biāo)識(shí)符”是定義的宏符號(hào)名(也稱宏名),其作用是在程序中以指定的標(biāo)識(shí)符來代替其后的常量表達(dá)式。利用宏定義可以在C語言源程序中用一個(gè)簡單的符號(hào)名來代替一個(gè)很長的字符串,還可以使用一些有一定意義的標(biāo)識(shí)符,提高程序的可讀性。
宏定義的作用范圍是整個(gè)文件,如果需在某個(gè)位置終止宏定義命令,則需使用“#undef標(biāo)識(shí)符常量表達(dá)式”命令。
2)帶參數(shù)的宏定義
帶參數(shù)的宏定義與符號(hào)常量定義的不同之處在于,對(duì)于源程序中出現(xiàn)的宏符號(hào)名
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 甘南民俗活動(dòng)方案
- 燃?xì)夥佬孤┬麄骰顒?dòng)方案
- 父親節(jié)班級(jí)讀書活動(dòng)方案
- 熱身足球活動(dòng)方案
- 愛心商家善舉活動(dòng)方案
- 烘焙實(shí)踐活動(dòng)方案
- 現(xiàn)場(chǎng)說課比賽活動(dòng)方案
- 烘培技能活動(dòng)方案
- 生態(tài)農(nóng)莊國慶活動(dòng)方案
- 愛心支教大賽活動(dòng)方案
- 學(xué)科建設(shè)研討活動(dòng)方案
- 千川投手培訓(xùn)課件
- 廣東省佛山禪城區(qū)七校聯(lián)考2025屆七下英語期末預(yù)測(cè)試題含答案
- 佛山市2024-2025高一下期末-物理試卷
- 建設(shè)工程(更新)融資投資立項(xiàng)項(xiàng)目可行性研究報(bào)告(非常詳細(xì))
- Unit 3 Same or Different?Section A 課件 人教版英語八年級(jí)上冊(cè)
- 2024年中級(jí)人民法院勞動(dòng)審判輔助人員招聘考試筆試試題(含答案)
- 中國熱射病診斷與治療指南(2025版)
- 公共藝術(shù)裝置項(xiàng)目管理流程
- 2025年下半年佛山市南海區(qū)建筑工程質(zhì)量檢測(cè)站招考編外工作人員易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- GB/T 45610-2025煤矸石回填塌陷區(qū)復(fù)墾技術(shù)規(guī)程
評(píng)論
0/150
提交評(píng)論