版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第3章
單片機(jī)C51程序設(shè)計基礎(chǔ)主要結(jié)合MCS-51單片機(jī)特點介紹C51的基本知識,重點講述與單片機(jī)軟件編程密切相關(guān)的內(nèi)容。第3章
單片機(jī)C51程序設(shè)計基礎(chǔ)C51概述3.1C51的編譯和編譯預(yù)處理3.2C51的基本語法3.3C51的程序結(jié)構(gòu)3.4C51的函數(shù)3.5C51的數(shù)組3.6
讀寫I/O端口的C51編程3.8C51的指針3.7早期的單片機(jī)系統(tǒng)主要采用匯編語言編寫程序,但是匯編語言程序的可讀性和可移植性都比較差,采用匯編語言編寫單片機(jī)應(yīng)用程序的開發(fā)周期長,而且調(diào)試和查錯比較困難。C語言既具有一般高級語言的特點,又能直接對計算機(jī)的硬件進(jìn)行操作,表達(dá)和運算能力也比較強(qiáng)。KeilC51是一種專為MCS-51系列單片機(jī)設(shè)計的C語言編譯器,支持用符合ANSI標(biāo)準(zhǔn)的C語言進(jìn)行程序設(shè)計,通常稱之為C51語言。3.1C51概述3.1.1程序結(jié)構(gòu)概述#include<reg51.h> //預(yù)處理命令//全局變量定義//函數(shù)聲明charfun() //功能函數(shù)定義{ …… //功能函數(shù)體}void函數(shù)名()interruptx //中斷函數(shù)定義{ …… //中斷函數(shù)體}voidmain() //主函數(shù){//局部變量定義//單片機(jī)寄存器初始化函數(shù) while(1) { …… //主函數(shù)體 }}一個C51源程序必須包括一個main函數(shù)。“#include<xxx.h>”語句是包含庫函數(shù)。用戶自定義函數(shù)是用戶自己定義、自己調(diào)用的函數(shù)。全局變量在程序的所有地方都可以賦值和讀出,包括中斷函數(shù)、主函數(shù)。如果使用中斷、定時器、串口等功能,則單片機(jī)相關(guān)寄存器的必須要初始化。主程序必須是閉環(huán)結(jié)構(gòu)。即是一個閉環(huán)循環(huán),采用while(1){…}(類似匯編語言例程中的LOOP:……LJMPLOOP),表示單片機(jī)的main函數(shù)中的部分代碼是循環(huán)執(zhí)行。注釋部分可以用“//注釋內(nèi)容”或“/*注釋內(nèi)容*/”分割。程序中必須采用英文標(biāo)點。3.1.1程序結(jié)構(gòu)概述為了更好地支持MCS-51單片機(jī)應(yīng)用系統(tǒng)的開發(fā),C51對標(biāo)準(zhǔn)C(ANSIC)進(jìn)行了擴(kuò)展,不僅完全支持C的標(biāo)準(zhǔn)指令,而且還進(jìn)行了諸多優(yōu)化。在C51中的關(guān)鍵字除了ANSIC標(biāo)準(zhǔn)的32個關(guān)鍵字之外,還根據(jù)MCS-51單片機(jī)的特點擴(kuò)展了相關(guān)的關(guān)鍵字,表3-1按用途列出了KeilC51編譯器擴(kuò)展的關(guān)鍵字。3.1.2
C51對標(biāo)準(zhǔn)C的擴(kuò)展表3-1KeilC51編譯器擴(kuò)展關(guān)鍵字關(guān)鍵字用途說明_at_地址定位為變量進(jìn)行存儲器絕對空間地址定位alien函數(shù)特性聲明用于聲明與PL/M51兼容函數(shù)small存儲器模式指定使用內(nèi)部數(shù)據(jù)存儲器空間compact存儲器模式指定使用外部“分頁尋址”數(shù)據(jù)存儲器空間large存儲器模式指定使用外部數(shù)據(jù)存儲器空間code存儲器類型聲明聲明程序存儲器空間data存儲器類型聲明指定直接尋址的內(nèi)部數(shù)據(jù)存儲器3.1.2
C51對標(biāo)準(zhǔn)C的擴(kuò)展續(xù)表3-1KeilC51編譯器擴(kuò)展關(guān)鍵字關(guān)鍵字用途說明bdata存儲器類型聲明指定可位尋址的內(nèi)部數(shù)據(jù)存儲器idata存儲器類型聲明指定間接尋址的內(nèi)部數(shù)據(jù)存儲器pdata存儲器類型聲明指定“分頁尋址”的外部數(shù)據(jù)存儲器xdata存儲器類型聲明指定外部數(shù)據(jù)存儲器bit位變量聲明聲明位變量sbit位變量聲明聲明一個可位尋址變量sfr特殊功能寄存器聲明聲明一個8位的特殊功能寄存器sfr16特殊功能寄存器聲明聲明一個16位的特殊功能寄存器interrupt中斷函數(shù)聲明定義一個中斷服務(wù)函數(shù)using工作寄存器組定義定義工作寄存器組R0~R7_priority_多任務(wù)優(yōu)先聲明規(guī)定RTX或RTX51Tiny的任務(wù)優(yōu)先級reentrant再入函數(shù)聲明定義一個再入函數(shù)_task_任務(wù)聲明定義實時多任務(wù)函數(shù)3.2.1編譯C51編譯器的作用是將C語言源程序翻譯成為MCS-51系列單片機(jī)的可執(zhí)行代碼。編譯命令分為源控制、列表控制和目標(biāo)控制三個大類。源控制命令用于宏定義以及確定需要進(jìn)行編譯的文件名。列表控制命令用于規(guī)定編譯后所產(chǎn)生列表文件的格式以及是否生成某些特殊內(nèi)容,所生成的列表文件擴(kuò)展名為“.LST”。目標(biāo)控制命令用于控制編譯之后生成目標(biāo)文件的形式和內(nèi)容,所生成的目標(biāo)文件擴(kuò)展名為“.OBJ”。目標(biāo)控制命令最多,作用最大,使用最頻繁。C51編譯器還可以生成擴(kuò)展名為“.I”和“.SRC”的輸出文件。C51編譯器在對源程序進(jìn)行編譯時將自動?xùn)隋e,并在編譯完成之后輸出0~3級錯誤提示。3.2C51的編譯和編譯預(yù)處理C語言與其他高級程序設(shè)計語言的一個主要區(qū)別就是對程序的編譯預(yù)處理功能。C語言的預(yù)處理命令類似于匯編語言中的偽指令。編譯器在對程序進(jìn)行編譯之前,先對程序中的編譯控制行進(jìn)行預(yù)處理,然后再將預(yù)處理的結(jié)果與整個C語言源程序一起進(jìn)行編譯,產(chǎn)生目標(biāo)代碼。3.2.2編譯預(yù)處理宏定義命令為#define,作用是用一個標(biāo)識符替換一個字符串。(1)不帶參數(shù)的宏定義。不帶參數(shù)的宏定義又稱符號常量定義,一般格式為:3.2.2編譯預(yù)處理-宏定義其中,“標(biāo)識符”是所定義的宏符號名(也稱宏名)。它的作用是在程序中使用指定的標(biāo)識符來代替所指定的常量表達(dá)式。#define標(biāo)識符常量表達(dá)式(2)帶參數(shù)的宏定義。帶參數(shù)的宏定義與符號常量定義的不同之處在于,對于源程序中出現(xiàn)的宏符號名不僅進(jìn)行字符串替換,而且還進(jìn)行參數(shù)替換。帶參數(shù)宏定義的一般格式為:其中,表達(dá)式內(nèi)包含了括號中所指定的參數(shù),這些參數(shù)稱為形式參數(shù),在以后的程序中它們將被實際參數(shù)所替換。#define宏符號名(參數(shù)表)表達(dá)式3.2.2編譯預(yù)處理-宏定義文件包含是將另一個指定的文件內(nèi)容包含進(jìn)來。文件包含命令的一般格式為:#include的功能是用指定文件的全部內(nèi)容替換該預(yù)處理行。采用<文件名>格式時,在頭文件目錄中查找指定文件;采用"文件名"格式時,在當(dāng)前目錄中査找指定文件,若沒找到,再到頭文件目錄中查找。#include通常放在C語言程序的開頭,被包含文件的類型通常為以“.h”為后綴的頭文件和以“.c”為后綴的源程序文件。#include<文件名>或#include"文件名"3.2.2編譯預(yù)處理-文件包含3.3.1常量常量又稱為標(biāo)量,它的值在程序執(zhí)行過程中不能改變。常量的數(shù)據(jù)類型有:1.整型。1234(十進(jìn)制整數(shù))、0x123(十六進(jìn)制整數(shù))、0123L(長整數(shù))。2.浮點型。有十進(jìn)制數(shù)表示形式和指數(shù)表示形式兩種。3.字符型。單引號內(nèi)的字符,如'a','b'等。對于不可顯示的控制字符,可以在該字符前面加一個反斜杠“\”組成轉(zhuǎn)義字符。4.字符串型。由雙引號""內(nèi)的字符組成,如"ABCD"、"$1234"等。3.3C51的基本語法變量是一種在程序執(zhí)行過程中其值能不斷變化的量。在使用一個變量之前,必須要進(jìn)行定義,用一個標(biāo)識符作為變量名并指出它的數(shù)據(jù)類型和存儲類型,以便編譯系統(tǒng)為它分配相應(yīng)的存儲單元。在C51中對變量進(jìn)行定義的格式如下:3.3.2變量[存儲種類]數(shù)據(jù)類型[存儲類型]變量名;變量的存儲種類有四種:自動(auto)、外部(extern)、靜態(tài)(static)和寄存器(register)。3.3.2變量-標(biāo)準(zhǔn)C數(shù)據(jù)類型數(shù)據(jù)類型位數(shù)字節(jié)數(shù)值域signedchar81-128~+127,有符號字符變量unsignedchar810~255,無符號字符變量signedint162-32768~+32767,有符號整型數(shù)unsignedint1620~65535,無符號整型數(shù)signedlong324-2147483648~+2147483647,有符號長整型數(shù)unsignedlong3240~+4294967695,無符號長整型數(shù)float324±1.175494E-38~±3.402823E+38,浮點數(shù)(精度6~7位)double648±4.940656458412465E-324~±1.797693134862316E+308,浮點數(shù)(精度15~16位)3.3.2變量-C51擴(kuò)展數(shù)據(jù)類型數(shù)據(jù)類型位數(shù)字節(jié)數(shù)值域bit1/0或1sfr810~255sfr161620~65535sbit1/0或1(1)位變量bitbit用于定義位變量的名字,編譯器會對其分配地址。位變量分配在內(nèi)部RAM的20H~2FH單元相應(yīng)的位區(qū)域,位地址范圍是00~7FH,共128個。用bit定義位變量的值可以是1,也可以是0。定義方法如下:針對MCS-51單片機(jī)的硬件特點,C51在標(biāo)準(zhǔn)C的基礎(chǔ)上,擴(kuò)展了4種數(shù)據(jù)類型,主要針對單片機(jī)片內(nèi)存儲區(qū)RAM。bit 位變量;3.3.2變量-C51擴(kuò)展數(shù)據(jù)類型(2)特殊功能寄存器sfr和sfr16特殊功能寄存器分布在片內(nèi)數(shù)據(jù)存儲區(qū)的地址單元80H~FFH之間?!皊fr”數(shù)據(jù)類型占用一個內(nèi)存單元,利用它可以直接對MCS-51單片機(jī)的特殊功能寄存器進(jìn)行定義。“sfr16”數(shù)據(jù)類型則占兩個內(nèi)存單元,利用它可以定義占兩個字節(jié)的特殊功能寄存器,在定義時的地址選用低位地址。定義方法如下:sfr
特殊功能寄存器名=地址;sfr16
特殊功能寄存器名=地址;(3)特殊功能位sbitsbit用于定義位變量的名字和地址。被定義的位變量是SFR中的可以進(jìn)行位尋址的確定位,該位變量的絕對地址是確定的且不用編譯器分配。利用sbit定義位變量名字和地址的方法有如下三種。①第一種方法(將位的絕對地址賦給位變量,位地址必須位于80H~FFH之間)。注意:不要把bit與sbit混淆。bit直接用于定義位變量,而sbit用于定義位變量的名字和地址。sbit 位變量名=位地址;②第二種方法(可尋址位位于特殊功能寄存器中)sbit 位變量名=特殊功能寄存器名^位位置;③第三種方法sbit 位變量名=字節(jié)地址^位位置;3.3.2變量-C51擴(kuò)展數(shù)據(jù)類型3.3.2變量-存儲類型存儲類型位數(shù)字節(jié)數(shù)值域與存儲空間對應(yīng)關(guān)系data810~127直接尋址片內(nèi)數(shù)據(jù)存儲器區(qū),訪問速度最快(128字節(jié))bdata1/0或1可位尋址片內(nèi)數(shù)據(jù)存儲區(qū),允許位與字節(jié)混合訪問(16字節(jié))idata810~255間接尋址片內(nèi)數(shù)據(jù)存儲區(qū),可訪問片內(nèi)全部RAM地址空間(256字節(jié))pdata810~255片外RAM的256字節(jié),由MOVX@Ri訪問xdata1620~65535片外64KB的RAM空間,由MOVX@DPTR訪問code1620~65535代碼存儲區(qū)(64KB),由MOVCA,@A+DPTR訪問C51存儲類型與MCS-51單片機(jī)存儲空間的對應(yīng)關(guān)系如下所示。3.3.2變量-存儲模式在固定的存儲器地址上進(jìn)行變量的傳遞,是C51標(biāo)準(zhǔn)特征之一。C51存儲模式分為以下幾種:(1)SMALL模式。所有變量都默認(rèn)位于MCS-51單片機(jī)內(nèi)部的數(shù)據(jù)存儲器,這與使用data指定存儲類型的方式一樣。在此模式下,變量訪問的效率高,但所有數(shù)據(jù)對象和堆棧必須使用內(nèi)部RAM。(2)COMPACT模式。變量被定義在分頁尋址的片外數(shù)據(jù)存儲器中,每一頁的片外存儲器的長度為256字節(jié),適用于變量不超過256字節(jié)的情況,對應(yīng)pdata存儲類型。(3)LARGE模式。變量被定義在片外數(shù)據(jù)存儲器中(最大可達(dá)64KB),對應(yīng)xdata存儲類型。該模式要比SMALL和COMPACT產(chǎn)生更多的代碼。3.3.2常用運算符與表達(dá)式-算數(shù)運算符算術(shù)運算符及其說明如下表所示。符號說明+加法運算-減法運算*乘法運算/除法運算%取模(余數(shù))運算++自增1--自減1符號說明&&邏輯與||邏輯或!邏輯非3.3.2常用運算符與表達(dá)式-邏輯運算符邏輯運算符及其說明如下表所示。符號說明>大于<小于>=大于或等于<=小于或等于==等于!=不等于>大于3.3.2常用運算符與表達(dá)式-關(guān)系運算符關(guān)系運算符及其說明如下表所示。符號說明&按位與|按位或^按位異或~按位取反<<按位左移>>按位右移&按位與3.3.2常用運算符與表達(dá)式-位運算符位運算符及其說明如下表所示。在實際的控制應(yīng)用中,人們常常想要改變I/O口中的某一位的值,而不影響其他位。如果I/O口是外部擴(kuò)展的,只能進(jìn)行字節(jié)操作,要想在這種場合下實現(xiàn)單獨的位控,就要利用位運算符進(jìn)行處理?!纠?-1】編寫程序?qū)U(kuò)展的I/O口PORT(只能字節(jié)操作)的PORT.5清0,PORT.1置1。參考程序:
#include<absacc.h>//定義片外I/O口變量PORT要用到頭文件absacc.h#definePORTXBYTE[0xffc0]//XBYTE是絕對地址訪問函數(shù)中的宏voidmain(){PORT=0x20;PORT=(PORT&0xdf)|0x02;}3.3.2常用運算符與表達(dá)式-位運算符賦值運算符及其說明如下表所示。符號說明=將一個數(shù)據(jù)的值賦給一個變量變量=表達(dá)式;賦值語句的格式如下:變量
復(fù)合復(fù)制運算符
表達(dá)式;復(fù)合賦值運算首先對變量進(jìn)行某種運算,然后將運算的結(jié)果再賦給該變量。復(fù)合運算的一般形式為:3.3.2常用運算符與表達(dá)式-賦值運算符指針和取地址運算符及其說明如下表所示。符號說明*取內(nèi)容&取變量的地址變量=*指針變量;指針變量=&目標(biāo)變量;取內(nèi)容(指針)和取地址的一般形式分別為:3.3.2常用運算符與表達(dá)式-指針和取地址運算符C51的程序按結(jié)構(gòu)可分為三類,即順序、分支和循環(huán)結(jié)構(gòu)。順序結(jié)構(gòu)是程序的基本結(jié)構(gòu),程序自上而下,從main()函數(shù)開始一直到程序運行結(jié)束,程序只有一條路可走,沒有其他的路徑可以選擇。3.4.1分支語句實現(xiàn)分支結(jié)構(gòu)的語句有:if語句和switch語句。1.if語句判定所給定的條件是否滿足,根據(jù)判定結(jié)果決定執(zhí)行哪種操作。if語句的基本結(jié)構(gòu)為:3.4C51的程序結(jié)構(gòu)if(表達(dá)式){語句;}3.4.1分支語句-if語句if(表達(dá)式){語句;}if(表達(dá)式){語句1;}else{語句2;}(2)形式2C51提供3種形式的if語句:(1)形式1if(表達(dá)式1){語句1;}elseif(表達(dá)式2){語句2;}elseif(表達(dá)式3){語句3;}……else{語句n;}(3)形式32.switch語句if語句只有兩個分支可供選擇,而switch語句是多分支選擇語句。switch語句的一般形式如下:switch(表達(dá)式){case常量表達(dá)式1:{語句1;}break;case常量表達(dá)式2:{語句2;}break;……case常量表達(dá)式n:{語句n;}break;default:{語句n+1;}}3.4.1分支語句-switch語句【例3-2】在單片機(jī)程序設(shè)計中,常用switch語句作為鍵盤按鍵按下的判別,并根據(jù)按下鍵的鍵號跳向各自的分支處理程序。參考程序:
keynum=keyscan();switch(keynum){case1: key1();break;//如果按下鍵的鍵值為1,則執(zhí)行函數(shù)key1()case2: key2();break;//如果按下鍵的鍵值為2,則執(zhí)行函數(shù)key2()case3: key3();break;//如果按下鍵的鍵值為3,則執(zhí)行函數(shù)key3()case4: key4();break;//如果按下鍵的鍵值為4,則執(zhí)行函數(shù)key4()……default:;break;}3.4.1分支語句-switch語句實現(xiàn)循環(huán)結(jié)構(gòu)的語句有:while語句、do-while語句和for語句。1.while語句while語句的語法形式為:3.4.2循環(huán)語句-while語句表達(dá)式是while循環(huán)能否繼續(xù)的條件,如果表達(dá)式為真,就重復(fù)執(zhí)行循環(huán)體語句;反之,則終止循環(huán)體內(nèi)的語句。while循環(huán)結(jié)構(gòu)的特點在于,循環(huán)條件的測試在循環(huán)體的開頭,如條件不成立,則循環(huán)體內(nèi)的重復(fù)操作一次也不能執(zhí)行。while(表達(dá)式){ 循環(huán)體語句;}2.do-while語句do-while語句的語法形式如下:do{ 循環(huán)體語句;}while(表達(dá)式);do-while語句的特點是先執(zhí)行內(nèi)嵌的循環(huán)體語句,再計算表達(dá)式,如果表達(dá)式的值為非0,則繼續(xù)執(zhí)行循環(huán)體語句,直到表達(dá)式的值為0時結(jié)束循環(huán)。3.4.2循環(huán)語句-do-while語句3.for語句for語句的語法形式如下:for(表達(dá)式1;表達(dá)式2;表達(dá)式3){ 循環(huán)體語句;}for的執(zhí)行過程如下:①計算“表達(dá)式1”,表達(dá)式1通常稱為“初值設(shè)定表達(dá)式”。②計算“表達(dá)式2”,表達(dá)式2通常稱為“終值條件表達(dá)式”,若滿足條件,轉(zhuǎn)下一步,若不滿足條件,則轉(zhuǎn)步驟⑤。③執(zhí)行一次for循環(huán)體。④計算“表達(dá)式3”,“表達(dá)式3”通常稱為“更新表達(dá)式”,執(zhí)行完成后,轉(zhuǎn)向步驟②。⑤結(jié)束循環(huán),執(zhí)行for循環(huán)之后的語句。3.4.2循環(huán)語句-for語句【例3-3】分別用while語句、do-while語句和for語句編寫求和程序,求1+2+3+…+10的和。
voidmain(){unsignedintnum,sum;num=1;sum=0;while(num<=10){sum+=num;num++;}}參考程序1:voidmain(){unsignedintnum,sum;num=1;sum=0;do{sum+=num;
num++;}while(num<=10);}參考程序2:3.4.2循環(huán)語句-for語句【例3-3】分別用while語句、do-while語句和for語句編寫求和程序,求1+2+3+…+10的和。
voidmain(){
unsignedintnum,sum;
sum=0;
for(num=1;num<=10;num++)
sum+=num;}參考程序3:3.4.2循環(huán)語句-for語句【例3-4】編寫賦值程序,使片內(nèi)RAM30H~3FH單元的內(nèi)容分別為00H~0FH。
dataunsignedcharbuffer[16]_at_0x30;voidmain(){
unsignedchari;
for(i=0;i<16;i++)
buffer[i]=i;}參考程序:在程序中,用關(guān)鍵字_at_實現(xiàn)對指定存儲空間絕對地址的訪問,使用_at_的格式如下:
[存儲類型]數(shù)據(jù)類型變量名_at_地址常數(shù);3.4.2循環(huán)語句-for語句3.5.1函數(shù)的定義和分類函數(shù)是一個完成一定相關(guān)功能的執(zhí)行代碼段。在高級語言中,函數(shù)與另外兩個名詞“子程序”和“過程”用來描述同樣的事情。一個C51程序必須至少有一個函數(shù),以main為名,稱為主函數(shù)。主函數(shù)是唯一的,整個程序從這個主函數(shù)開始執(zhí)行。從結(jié)構(gòu)上分,C51函數(shù)可分為主函數(shù)main()和普通函數(shù)兩種。而普通函數(shù)又分為兩種:標(biāo)準(zhǔn)庫函數(shù)和用戶自定義函數(shù)。
3.5C51的函數(shù)每個庫函數(shù)都在相應(yīng)的頭文件中給出了函數(shù)原型聲明,用戶如果需要使用庫函數(shù),必須在程序的開頭處采用預(yù)處理命令#include將有關(guān)頭文件包含進(jìn)來。
例如,為便于對特殊功能寄存器進(jìn)行讀寫操作,我們要在程序開頭處使用以下命令:3.5.1函數(shù)的定義和分類-C51標(biāo)準(zhǔn)庫函數(shù)#include<reg51.h>#include<stdio.h>調(diào)用輸出函數(shù)printf時,我們要在程序開頭處使用以下命令:(1)字符函數(shù)CTYPE.H。通常用來對字符做檢查和轉(zhuǎn)換。(2)內(nèi)部函數(shù)INTRINS.H。_crol_、_cror_可以實現(xiàn)變量循環(huán)移位,_nop_可以執(zhí)行一次空操作。(3)標(biāo)準(zhǔn)輸入/輸出函數(shù)STDIO.H。標(biāo)準(zhǔn)I/O函數(shù)通過MCS-51單片機(jī)的串行口讀寫數(shù)據(jù)。(4)標(biāo)準(zhǔn)函數(shù)STDLIB.H。可以完成數(shù)據(jù)類型轉(zhuǎn)換以及存儲器分配操作。(5)字符串處理函數(shù)STRING.H。通常接收串指針作為輸入值。(6)絕對地址訪問函數(shù)ABSACC.H。(7)專用寄存器文件REGxx.H。包括了51系列所有的SFR及其中可尋址位(除P0~P3口外)的定義。3.5.1函數(shù)的定義和分類-C51標(biāo)準(zhǔn)庫函數(shù)(1)無參函數(shù)此種函數(shù)在被調(diào)用時,既無參數(shù)輸入,也不返回結(jié)果給調(diào)用函數(shù),只是為完成某種操作而編寫的函數(shù)。無參函數(shù)的定義形式為:無參函數(shù)一般不帶返回值,因此函數(shù)的返回值類型標(biāo)識符可省略。返回值類型標(biāo)識符函數(shù)名(){ 函數(shù)體;}3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)voiddelay1s(){ unsignedinti,j; for(i=0;i<1000;i++) for(j=0;j<125;j++);}【例3-5】已知單片機(jī)的fosc=12MHz,編寫一個延時1s的函數(shù)。分析:晶振頻率fosc=12MHz時,一個機(jī)器周期為12/fosc=1μs,因此延時1s需要消耗1000000個機(jī)器周期(1000000μs)。根據(jù)經(jīng)驗,利用C51的for語句進(jìn)行內(nèi)部循環(huán)大約延時8個機(jī)器周期(不同的編譯器會產(chǎn)生不同的延時),因此將for語句循環(huán)125次可以得到1ms,采用兩個for嵌套語句可以得到1s。參考程序:3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)(2)有參函數(shù)調(diào)用此種函數(shù)時,必須提供實際的輸入函數(shù)。有參函數(shù)的定義形式為:返回值類型標(biāo)識符函數(shù)名(形式參數(shù)列表)形式參數(shù)說明{ 函數(shù)體;}3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)【例3-6】已知單片機(jī)的fosc=12MHz,編寫一個延時nms的函數(shù)。
voiddelaynms(unsignedintn){
unsignedinti,j;
for(i=0;i<n;i++)
for(j=0;j<125;j++);}參考程序:3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)【例3-7】定義一個函數(shù)max(),用于求兩個數(shù)中的大數(shù)。
inta,b;intmax(a,b){ if(a>b)return(a); else
return(b);}參考程序:3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)(3)空函數(shù)此種函數(shù)體內(nèi)是空白的。調(diào)用空函數(shù)時,什么工作也不做,不起任何作用。定義空函數(shù)的目的,并不是為了執(zhí)行某種操作,而是為了以后程序功能的擴(kuò)充??蘸瘮?shù)的定義形式為:返回值類型標(biāo)識符函數(shù)名(){}3.5.1函數(shù)的定義和分類-用戶自定義函數(shù)在一個函數(shù)中需要用到某個函數(shù)的功能時,就調(diào)用該函數(shù)。調(diào)用者稱為主調(diào)函數(shù),被調(diào)用者稱為被調(diào)函數(shù)。1.函數(shù)調(diào)用的一般形式函數(shù)調(diào)用的一般形式:3.5.2函數(shù)的調(diào)用-函數(shù)調(diào)用的一般形式函數(shù)名(實際參數(shù)列表);若被調(diào)函數(shù)是有參函數(shù),則主調(diào)函數(shù)必須把被調(diào)函數(shù)所需的參數(shù)傳遞給被調(diào)函數(shù)。傳遞給被調(diào)函數(shù)的數(shù)據(jù)稱為實際參數(shù)(簡稱實參),必須與形參的數(shù)據(jù)在數(shù)量、類型和順序上都一致。實參可以是常量、變量和表達(dá)式。實參對形參的數(shù)據(jù)是單向的,即只能將實參傳遞給形參。2.函數(shù)調(diào)用的方式(1)函數(shù)調(diào)用語句。把被調(diào)用函數(shù)的函數(shù)名作為主調(diào)函數(shù)的一個語句。例如:(2)函數(shù)結(jié)果作為表達(dá)式的一個運算對象。例如:要求被調(diào)用函數(shù)帶有return語句,以便返回一個明確的數(shù)值參加表達(dá)式的運算。(3)函數(shù)參數(shù)。被調(diào)用函數(shù)作為另一個函數(shù)的實際參數(shù)。例如:3.5.2函數(shù)的調(diào)用-函數(shù)調(diào)用的方式delay1s();result=2*max(a,b);m=max(a,max(u,v));3.函數(shù)調(diào)用的條件在一個函數(shù)調(diào)用另一個函數(shù)時,需具備以下條件:(1)被調(diào)用函數(shù)必須是已經(jīng)存在的函數(shù)。(2)如果程序中使用了庫函數(shù),或使用了不在同一文件中的另外自定義函數(shù),則應(yīng)該在程序的開頭處使用#include包含語句。(3)如果程序中使用了自定義函數(shù),且該函數(shù)與調(diào)用它的函數(shù)同在一個文件中,則應(yīng)根據(jù)主調(diào)用函數(shù)與被調(diào)用函數(shù)在文件中的位置,決定是否對被調(diào)用函數(shù)做出說明。①如果被調(diào)用函數(shù)在主調(diào)用函數(shù)之后,一般應(yīng)在主調(diào)用函數(shù)中,在被調(diào)用函數(shù)調(diào)用之前,對被調(diào)用函數(shù)的返回值類型做出說明。②如果被調(diào)用函數(shù)出現(xiàn)在主調(diào)用函數(shù)之前,不用對被調(diào)用函數(shù)進(jìn)行說明。通常把主函數(shù)main()放在最后。③如果在文件開頭,即所有函數(shù)定義之前已經(jīng)說明了函數(shù)的類型,則在主調(diào)用函數(shù)中不必對所調(diào)用的函數(shù)再做返回值類型說明。3.5.2函數(shù)的調(diào)用-函數(shù)調(diào)用的條件中斷服務(wù)函數(shù)的一般形式為:其中:interrupt后面的n是中斷編號,n的取值范圍為0~31。編譯器從8n+3處產(chǎn)生中斷向量,具體的中斷編號n和中斷向量取決于不同的MCS-51系列單片機(jī)芯片。m用來選擇MCS-51單片機(jī)中不同的工作寄存器組。由于C51編譯器在編譯時對聲明為中斷服務(wù)程序的函數(shù)自動添加了相應(yīng)的現(xiàn)場保護(hù)、阻斷其他中斷、返回時自動恢復(fù)現(xiàn)場等處理的程序段,因而在編寫中斷服務(wù)函數(shù)時可不必考慮這些問題。3.5.3中斷服務(wù)函數(shù)函數(shù)類型函數(shù)名(形式參數(shù)表)interruptn[usingm]3.6.1數(shù)組的定義數(shù)組是同類數(shù)據(jù)的一個有序結(jié)合,用數(shù)組名來標(biāo)識。整型變量的有序結(jié)合稱為整型數(shù)組,字符型變量的有序結(jié)合稱為字符數(shù)組,……。數(shù)組中的數(shù)據(jù),稱為數(shù)組元素。1.一維數(shù)組具有一個下標(biāo)的數(shù)組元素組成的數(shù)組稱為一維數(shù)組,一維數(shù)組的形式如下:其中,數(shù)組名是一個標(biāo)識符,元素個數(shù)是一個常量表達(dá)式,不能是含有變量的表達(dá)式。在定義數(shù)組時,可以對數(shù)組進(jìn)行整體初始化,若定義后對數(shù)組賦值,則只能對每個元素分別賦值。3.6C51的數(shù)組類型說明符數(shù)組名[元素個數(shù)];2.二維數(shù)組或多維數(shù)組具有兩個或兩個以上下標(biāo)的數(shù)組,稱為二維數(shù)組或多維數(shù)組。定義二維數(shù)組的一般形式如下:其中,數(shù)組名是一個標(biāo)識符,行數(shù)和列數(shù)都是常量表達(dá)式。。二維數(shù)組可以在定義時進(jìn)行整體初始化,也可在定義后單個地進(jìn)行賦值。3.6.1數(shù)組的定義類型說明符數(shù)組名[行數(shù)][列數(shù)];3.字符數(shù)組若一個數(shù)組的元素是字符型的,則該數(shù)組就是一個字符數(shù)組。例如:C51還允許用字符串直接給字符數(shù)組置初值,例如:chara[10]={'H','E','L','L','O','!','\0'};chara[10]={"HELLO!"};用雙引號括起來的一串字符,稱為字符串常量,C51編譯器會自動地在字符串末尾加上結(jié)束符‘\0’。用單引號括起來的字符為字符的ASCII碼值,而不是字符串。一個字符串可以用一維數(shù)組來裝入,但數(shù)組的元素數(shù)目一定要比字符多一個,以便C51編譯器自動在其后面加入結(jié)束符'\0'。3.6.1數(shù)組的定義【例3-8】使用查表法,計算數(shù)0~9的平方。
#defineucharunsignedchar ucharcodesquare[10]={0,1,4,9,16,25,36,49,64,81};ucharfuction(ucharnumber){
returnsquare[number];} voidmain() {
ucharresult;
result=fuction(7);
while(1);}參考程序:3.6.2數(shù)組的應(yīng)用在C語言中為了實現(xiàn)直接對內(nèi)存單元進(jìn)行操作,引入了指針類型的數(shù)據(jù)。正確地使用指針類型數(shù)據(jù),可以有效地表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu),直接處理內(nèi)存地址,而且可以更為有效地使用數(shù)組。3.7.1指針與地址一個程序的指令、常量和變量等都要存放在機(jī)器內(nèi)存單元中,而機(jī)器內(nèi)存是按字節(jié)來劃分存儲單元的,給內(nèi)存中每個字節(jié)都賦予一個編號,這就是存儲單元的地址。各個存儲單元中所存放的數(shù)據(jù),稱為該存儲單元的內(nèi)容。所謂尋址,就是按照內(nèi)存單元的地址來訪問該存儲單元中的內(nèi)容,即按地址來讀或?qū)懺搯卧械臄?shù)據(jù)。3.7C51的指針-指針與地址指針類型數(shù)據(jù)是專門用來確定其他類型數(shù)據(jù)地址的,一個變量的地址就稱為該變量的指針。如果有一個變量專門用來存放另一個變量的地址,則稱之為“指針變量”。變量的指針就是該變量的地址,而指針變量里面存放的是另一個變量在內(nèi)存中的地址,擁有這個地址的變量稱為該指針變量所指向的變量。為了表示指針變量和它所指向的變量之間的關(guān)系,C語言中用符號“*”來表示“指向”。3.7.1指針與地址符號“*”稱為指針運算符,它只能與指針變量一起聯(lián)用,結(jié)果是得到該指針變量所指向變量的值。指針的定義與一般變量的定義類似,其一般形式如下:其中“標(biāo)識符”是所定義的指針名?!皵?shù)據(jù)類型”說明該指針?biāo)赶虻淖兞康念愋??!按鎯ζ黝愋?”和“存儲器類型2”是可選項,它是KeilC51編譯器的一種擴(kuò)展?!按鎯ζ黝愋?”選項用于指定指針的存儲器空間。“存儲器類型2”選項用于指定指針本身的存儲器空間。一般指針可用于存取任何變量而不必考慮變量在MCS-51單片機(jī)存儲器空間的位置,許多C51庫函數(shù)采用了一般指針,函數(shù)可以利用一般指針來存取位于任何存儲器空間的數(shù)據(jù)。3.7.2指針的定義數(shù)據(jù)類型[存儲器類型1]*[存儲器類型2]標(biāo)識符;KeilC51定義一般指針的語句如下:上面的一般指針c_ptr、i_ptr、l_ptr全部位于MCS-51單片機(jī)的片內(nèi)數(shù)據(jù)存儲器中。如果在定義一般指針時帶有“存儲器類型2”選項,則可指定一般指針本身的存儲器空間位置,例如:3.7.2指針的定義-一般指針char*c_ptr;int*i_ptr;long*l_ptr;
char*xdatastrptr; //位于xdata空間的一般指針int*datanumptr; //位于data空間的一般指針long*idatavarptr; //位于idata空間的一般指針基于存儲器的指針?biāo)笇ο缶哂忻鞔_的存儲器空間,長度可為1個字節(jié)(存儲器類型為IDATA、DATA、PDATA)或2個字節(jié)(存儲器類型為CODE、XDATA),例如:與一般指針類似,若定義時帶有“存儲器類型2”選項,則可指定基于存儲器的指針本身的存儲器空間位置,例如:3.7.2指針的定義-基于存儲器的指針chardata*str;
//指向data空間char型數(shù)據(jù)指針intxdata*numtab;//指向xdata空間int型數(shù)據(jù)指針longcode*powtab;//指向code空間long型數(shù)據(jù)指針chardata*xdatastr; intxdata*datanumtab; longcode*idatapowtab; 指針是含有一個數(shù)據(jù)對象地址的特殊變量,指針變量中只能存放地址。與指針有關(guān)的運算符有兩個,它們是取地址運算符&和間接訪問運算符*。例如:&a為取變量a的地址,*p為指針p所指向的變量。變量定義:指針賦值:指針引用:3.7.3指針的引用pi=&i;//將變量i的地址賦給指針pi,使pi指向ipx=&x;//px指向xpy=&y;//py指向y*pi=0; //等價于i=0;*pi+=1; //等價于i+=1;(*pi)++; //等價于i++;inti,x,y,*pi,*px,*py;對單片機(jī)I/O端口進(jìn)行編程控制時,需要對I/O端口的特殊功能寄存器進(jìn)行聲明,在C51的編譯器中,這項聲明包含在頭文件reg51.h中,編程時可通過預(yù)處理命令“#include<reg51.h>”把這個頭文件包含進(jìn)去。C51讀單片機(jī)的I/O端口(以P1為例):C51寫單片機(jī)的I/O端口(以P1為例):C51讀單片機(jī)的I/O端口的某個引腳(以P1.3為例):C51寫單片機(jī)的I/O端口的某個引腳(以P1.3為例):3.8讀寫I/O端口的C51編程P1=數(shù)值;sbitP1_3=P1^3;位變量=P1_3;變量=P1;sbitP1_3=P1^3;P1_3=位值;【例3-9】P1.0輸入的位直接由P1.1口輸出。
#include<reg51.h>sbitP1_0=P1^0;sbitP1_1=P1^1;voidmain(){Pl_0=1;//P1是準(zhǔn)雙向口,讀P1.0之前先給P1.0寫1while(1)//循環(huán)讀P1.0并送至P1.1{P1_1=P1_0;}}參考程序:3.8讀寫I/O端口的C51編程【例3-10】89C51的P1口接了8個發(fā)光二極管,如下圖所示,請編程實現(xiàn)發(fā)光二極管由右向左流水顯示。
3.8讀寫I/O端口的C51編程voidmain(){ P1=0xfe; while(1)
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度電子廢棄物回收處理設(shè)備研發(fā)與生產(chǎn)合同模板3篇
- 2025年度大數(shù)據(jù)服務(wù)合同編典型保證合同
- 2025年度法律服務(wù)機(jī)構(gòu)學(xué)員法律知識普及合同3篇
- 2025年度鋼鐵產(chǎn)品年購銷合同規(guī)范
- 2025年度廣告海報印刷品批量制作與印制合同
- 花卉租賃合同與花卉租賃合同
- 永州職業(yè)技術(shù)學(xué)院《航拍技術(shù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 義烏工商職業(yè)技術(shù)學(xué)院《影視概念設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 餐飲業(yè)研發(fā)人員勞動合同模板3篇
- 高溫鍋爐購銷合同3篇
- 30題紀(jì)檢監(jiān)察位崗位常見面試問題含HR問題考察點及參考回答
- 室內(nèi)墻面噴涂與涂飾
- Unit2HowoftendoyouexerciseSectionA(1a-2d)教案人教版英語八年級上冊
- 光伏電站事故處理規(guī)程
- 山東專升本計算機(jī)-演示文稿軟件-Powerpoint-2010課件(新版考試大綱)
- 親子鑒定內(nèi)容 報告書范本
- 【課件】洋流教學(xué)課件高中地理人教版(2019)選擇性必修1
- 社區(qū)服務(wù)中心
- 五金產(chǎn)品檢驗作業(yè)指導(dǎo)書
- 商業(yè)天然氣灶具用氣量明細(xì)
- 錨桿密實度檢測
評論
0/150
提交評論