版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第10章目錄10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)類型10.1.2C51中擴(kuò)充的數(shù)據(jù)類型10.1.3C51中的運(yùn)算符10.1.4C51中的語句及程序結(jié)構(gòu)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2.4定時(shí)器程序設(shè)計(jì)舉例10.2.5串行通信程序設(shè)計(jì)舉例第10章目錄10.1C51程序設(shè)計(jì)基礎(chǔ)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)類型C語言中的數(shù)據(jù)有常量和變量之分,當(dāng)我們?cè)诰帉憜纹瑱C(jī)程序時(shí),用到的相關(guān)變量在單片機(jī)的內(nèi)存中都要占據(jù)一定的存儲(chǔ)空間,變量大小不同,所占據(jù)的空間就不同,所以,“變量”數(shù)據(jù)的大小是有限制的,我們不能隨意給一個(gè)變量賦任意大小的值。為了合理利用內(nèi)存空間,我們?cè)诰幊虝r(shí)就要選擇大小合適的數(shù)據(jù),不同的數(shù)據(jù)類型也就代表了不同大小的數(shù)據(jù),所以,我們?cè)谑褂米兞恐?,首先要聲明這個(gè)變量的類型,以便讓編譯器提前從內(nèi)存中為其分配空間。表10-1列出了C51的基本數(shù)據(jù)類型。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)類型表10-1C51的基本數(shù)據(jù)類型數(shù)據(jù)類型關(guān)鍵字長度取值范圍字符型字符型char1字節(jié)-128~+127無符號(hào)字符型usignedchar1字節(jié)0~255有符號(hào)字符型signedchar1字節(jié)-128~+127整型基本型無符號(hào)usignedint2字節(jié)0~65535有符號(hào)[signed]int2字節(jié)-32768~+32767短整型無符號(hào)usignedshort[int]2字節(jié)0~65535有符號(hào)[signed]short[int]2字節(jié)-32768~+32767長整型無符號(hào)usignedlong[int]4字節(jié)0~4294967295有符號(hào)[signed]long[int]4字節(jié)-2147483648~+2147483647浮點(diǎn)型單精度float4字節(jié)-3.4×10-38~3.4×1038雙精度double8字節(jié)-1.7×10-308~1.7×10308長雙精度longdouble16字節(jié)-1.2×10-4932~1.7×104932位類型bit1位0~110.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)類型說明:(1)在單片機(jī)中,所有的數(shù)據(jù)都是以二進(jìn)制的形式存儲(chǔ)在存儲(chǔ)器中的,其中,1個(gè)字節(jié)=8位二進(jìn)制(即1Byte=8bit)。(2)在C語言中:shortint即為int,longint即為long。(3)前面若無unsigned則一律認(rèn)為是signed型。(4)一般情況下,float型數(shù)據(jù)只能提供7位有效數(shù)字,double型數(shù)據(jù)能夠提供15~16位有效數(shù)字,但是這個(gè)精度還和編譯器有關(guān)系,并不是所有的編譯器都遵守這條原則。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)類型例如:floatx;x=32.45678912;由于float類型的有效數(shù)字是7位,故x=32.45679,若將x改成double類型的則能將32.45678912全部存放在x中,所以,在聲明變量時(shí)應(yīng)根據(jù)其使用情況來為其選擇類型。例如:inti=9;在內(nèi)存中占16位(即2個(gè)字節(jié)的存儲(chǔ)單元)。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.1C51中的基本數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)類型在C51中除以上基本數(shù)據(jù)類型外,為了適應(yīng)單片機(jī)程序開發(fā)的需要又?jǐn)U充了如下的數(shù)據(jù)類型。位變量聲明bit:聲明一個(gè)位變量。8位寄存器聲明sfr:聲明一個(gè)8位寄存器。16位寄存器聲明sfr16:聲明一個(gè)16位寄存器。特殊功能位聲明sbit:聲明特殊功能寄存器中的某一位。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)類型bitflag;
說明:聲明了一個(gè)變量名為flag的位變量。sfrTCON=0x88H;
說明:單片機(jī)內(nèi)部有很多特殊功能寄存器(sfr),每個(gè)sfr在單片機(jī)內(nèi)部都分配有唯一的一個(gè)地址,當(dāng)我們?cè)诔绦蛑惺褂胹fr時(shí),我們一般通過聲明將相應(yīng)的地址編號(hào)賦給一個(gè)名稱,以后通過該名稱來使用相應(yīng)sfr,其中這些聲明絕大多數(shù)都包含在相應(yīng)的頭文件(如:reg51.h)中。本例中TCON是單片機(jī)的定時(shí)器/計(jì)數(shù)器控制寄存器,它在單片機(jī)內(nèi)存中的地址為0x88H,經(jīng)過該語句聲明以后,如在后面的程序中使用該寄存器則只需使用其名稱TCON即可,當(dāng)程序進(jìn)行編譯時(shí),編譯器也知道實(shí)際要操作的是單片機(jī)內(nèi)部0x88地址處的這個(gè)寄存器,而TCON僅僅是這個(gè)地址的一個(gè)代號(hào)或名稱而已,當(dāng)然,我們也可以聲明成其他的名稱。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)類型sfr16T1=0x8BH;
說明:
聲明了一個(gè)16位SFR,起始地址為0x8BH,道理與上例相同不再重復(fù)解釋。sbitTR0=TCON^4;說明:
首先應(yīng)該有sfrTCON=0x88H;這句的聲明后,我們才知道TCON是定時(shí)器/計(jì)數(shù)器控制寄存器的名稱,它是一個(gè)8位的寄存器,其中,TCON^0為最低位,TCON^7為最高位,通過本例的聲明,以后當(dāng)我們使用TCON^4時(shí),直接操作TR0即可,當(dāng)然,我們也可以將TCON^4聲明成其他的名稱。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.2C51中擴(kuò)充的數(shù)據(jù)10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符絕大多數(shù)的程序都需要對(duì)數(shù)據(jù)進(jìn)行加工處理,即進(jìn)行運(yùn)算,要進(jìn)行運(yùn)算就得規(guī)定可以使用的運(yùn)算符,C51中的運(yùn)算符與C語言基本相同,在單片機(jī)程序開發(fā)過程中最常用的主要有算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符和位運(yùn)算符等。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符說明:(1)“==”表示測試兩數(shù)是否相等,如a==b,測試a和b中的值是否相等。(2)“!=”表示測試兩數(shù)是否不相等,如a!=b,測試a和b中的值是否不相等。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符說明:(1)右移,操作符為“>>”,每執(zhí)行一次右移指令,被操作數(shù)的各位依次向右移動(dòng)一位,其中,最高位補(bǔ)0,最低位移入PSW寄存器CY位,CY位中原來的數(shù)被覆蓋。如圖10-1所示。(2)左移,操作符為“<<”,每執(zhí)行一次左移指令,被操作數(shù)的各位依次向左移動(dòng)一位,其中,最高位移入PSW寄存器CY位,CY位中原來的數(shù)被覆蓋,最低位補(bǔ)0,如圖10-2所示。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符其他運(yùn)算符賦值運(yùn)算符:=條件運(yùn)算符:?:逗號(hào)運(yùn)算符:,指針運(yùn)算符:*和&求字節(jié)運(yùn)算符:sizeof強(qiáng)制類型轉(zhuǎn)換運(yùn)算符:(類型)成員運(yùn)算符:.—>下標(biāo)運(yùn)算符:[]其他10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.3C51中的運(yùn)算符10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程序結(jié)構(gòu)1、語句
C51程序是由語句組成的,其中,語句可分為以下幾類:(1)表達(dá)式語句:
由一個(gè)表達(dá)式(賦值表達(dá)式、算術(shù)運(yùn)算表達(dá)式、關(guān)系表達(dá)式、邏輯表達(dá)式等)加上一個(gè)分號(hào)構(gòu)成,最典型的就是賦值表達(dá)式構(gòu)成的賦值語句。例如:x=3.6;(2)函數(shù)調(diào)用語句:由一個(gè)函數(shù)調(diào)用加上一個(gè)分號(hào)構(gòu)成。例如:printf(“Helloeveryone!”);說明:在屏幕上輸出顯示Helloeveryone!10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程序結(jié)構(gòu)(3)控制語句:條件語句:if、switch。循環(huán)語句:for、while、dowhile??刂妻D(zhuǎn)移語句:break、continue、return、goto。(4)復(fù)合語句:
用{}把一些語句和聲明括起來就構(gòu)成了復(fù)合語句。{floatx=3,y=9,z;z=x+y;printf(“z=%f”,z);}(5)空語句:只有一個(gè)分號(hào);什么也不做,可以作為程序流程的轉(zhuǎn)向點(diǎn),也可用作循環(huán)語句的循環(huán)體(循環(huán)體是空語句)。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程序結(jié)構(gòu)2、程序結(jié)構(gòu)由以上語句可以構(gòu)成C程序的三大結(jié)構(gòu),即順序結(jié)構(gòu)、選擇結(jié)構(gòu)(分支結(jié)構(gòu))、循環(huán)結(jié)構(gòu)。(1)順序結(jié)構(gòu):僅僅是簡單的一個(gè)語句一個(gè)語句的執(zhí)行。(2)選擇結(jié)構(gòu):主要由條件語句構(gòu)成。(3)循環(huán)結(jié)構(gòu):主要由循環(huán)語句構(gòu)成,與標(biāo)準(zhǔn)C語言一樣,循環(huán)結(jié)構(gòu)中可以使用break、continue、return、goto。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.4C51中的語句及程10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件C51中已定義的常用的頭文件主要有如下類別:absacc.h---包含允許直接訪問8051不同存儲(chǔ)區(qū)的宏定義。assert.h---文件定義assert宏,可以用來建立程序的測試條件。ctype.h---字符轉(zhuǎn)換和分類程序。math.h---數(shù)學(xué)函數(shù)程序。reg51.h---51的特殊寄存器聲明。reg52.h---52的特殊寄存器聲明。setjmp.h---定義jmp_buf類型和setjmp和longjmp程序的原型。stdarg.h---可變長度參數(shù)列表程序。stdlib.h---存儲(chǔ)器分配程序。stdio.h---流輸入和輸出程序。string.h---字符轉(zhuǎn)操作程序,緩沖區(qū)操作程序。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件
在單片機(jī)程序中,經(jīng)常使用的頭文件主要有math.h、reg51.h或reg52.h、stdio.h等。1、頭文件math.h頭文件math.h是數(shù)學(xué)函數(shù)庫,各種數(shù)學(xué)計(jì)算函數(shù)的具體實(shí)現(xiàn)就放在文件math.h里,比如,平方根函數(shù)sqrt、絕對(duì)值函數(shù)fabs、指數(shù)函數(shù)exp、正弦函數(shù)sin、余弦函數(shù)cos等,當(dāng)我們需要使用時(shí)可以直接調(diào)用這些函數(shù)。2、頭文件reg51.h和reg52.h頭文件reg51.h或reg52.h是聲明51單片機(jī)或52單片機(jī)特殊功能寄存器和位寄存器的,這兩個(gè)頭文件中大部分內(nèi)容是一樣的,51單片機(jī)比52單片機(jī)少一個(gè)定時(shí)/計(jì)數(shù)器T2,因此,reg51.h中也就比reg52.h中少了幾行對(duì)寄存器T2聲明的內(nèi)容。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件
在單片機(jī)程序中,經(jīng)常使用的頭文件主要有math.h、reg51.h或reg52.h、stdio.h等。⒊、頭文件stdio.h包含了與標(biāo)準(zhǔn)輸入輸出庫有關(guān)的變量定義和宏定義以及對(duì)函數(shù)的聲明,標(biāo)準(zhǔn)輸入輸出函數(shù)主要有printf、scanf、putchar、getchar等。除以上已定義的頭文件外,用戶也可以根據(jù)自己的需要定義擴(kuò)展名為.h的頭文件,存放到指定的目錄下,在編程中可以直接使用。10.1C51程序設(shè)計(jì)基礎(chǔ)10.1.5C51中的頭文件10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例【例10-1】在8051單片機(jī)中,利用定時(shí)器T0產(chǎn)生50ms的定時(shí)時(shí)間。通過本例我們將對(duì)頭文件、主函數(shù)main()、注釋等三個(gè)方面的知識(shí)點(diǎn)做講解。程序代碼如下:#include<reg51.h>//包含頭文件voidmain() {TMOD=0x01;
//設(shè)置定時(shí)器0為方式1、定時(shí)模式TH0=(65536-45872)/256//裝初值TL0=(65536-45872)%256; TR0=1; //啟動(dòng)定時(shí)器0while(1)//程序停止}10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例說明:(1)按照定時(shí)/計(jì)數(shù)器的初始化流程,首先設(shè)置TMOD=0x01,置T0工作于方式1、定時(shí)模式,給TH0和TL0裝入初值,之后啟動(dòng)定時(shí)器開始計(jì)時(shí),獲得50ms的時(shí)間。(2)下面說一下初值的計(jì)算。晶振頻率為fosc=11.0592Mhz機(jī)器周期T=12*1/fosc=12*1/11.0592Mhz=1.09μs計(jì)數(shù)值=50×10-3/(1.09×10-6)=45872因單片機(jī)的定時(shí)器是加法計(jì)數(shù)器,如果想獲得50ms的定時(shí)時(shí)間,我們就要給TH0和TL0裝入計(jì)數(shù)初值X,在這個(gè)初值的基礎(chǔ)上計(jì)45872個(gè)數(shù)至65536(方式1的溢出值216),定時(shí)器溢出,此時(shí)剛好50ms。因此,計(jì)數(shù)初值X=65536-45872=19664。在編寫程序時(shí)要將計(jì)數(shù)值轉(zhuǎn)換成16進(jìn)制的,我們采用下面的方法轉(zhuǎn)換,把19664對(duì)256求模,即19664/256裝入THO中,把19664對(duì)256求余,即19664%256裝入TLO中。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例1、頭文件(1)頭文件包含的書寫方法:兩種當(dāng)使用#include<reg51.h>時(shí)(即本例中所使用的方法),編譯器先進(jìn)入到軟件安裝文件夾(Keil\C51\INC)處開始搜索這個(gè)頭文件,如果這個(gè)文件夾下沒有引用的頭文件,編譯器將會(huì)報(bào)錯(cuò)。當(dāng)使用#include“reg51.h”時(shí),編譯器先進(jìn)入到當(dāng)前工程所在文件夾處開始搜索該頭文件,如果當(dāng)前工程所在文件夾下沒有該頭文件,編譯器將繼續(xù)回到軟件安裝文件夾處搜索這個(gè)頭文件,若仍然找不到該頭文件,編譯器將報(bào)錯(cuò)。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例1、頭文件(2)頭文件中的內(nèi)容:
在安裝好Keiluvision3編譯軟件后,我們可以到Keil\C51\INC這個(gè)文件夾下找到頭文件reg51.h或者在Keil中編輯程序時(shí)鼠標(biāo)移動(dòng)到reg51.h上,單擊右鍵選擇Opendocument<reg51.h>也可以打開,打開之后其具體內(nèi)容參考教材。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例1、頭文件說明:在該頭文件中聲明了51系列單片機(jī)內(nèi)部的21個(gè)特殊功能寄存器的名稱和可以進(jìn)行位操作的特殊功能寄存器中的各個(gè)位的名稱。在這里主要用到了前面講到的sfr和sbit這兩個(gè)關(guān)鍵字。例如:sfrTMOD=0x89;把單片機(jī)內(nèi)部地址0x89處的這個(gè)寄存器重新命名為TMOD,以后在程序中使用該寄存器時(shí)直接使用TMOD即可,如上例所示。其實(shí),對(duì)單片機(jī)而言它只知道它的內(nèi)部地址0x89是什么,而并不知道TMOD是什么,現(xiàn)在通過sfrTMOD=0x89;這條語句,單片機(jī)就清楚了程序中的TMOD具體指什么了。因此,以后凡是編寫5l內(nèi)核單片機(jī)程序時(shí),我們?cè)谠创a的前面都應(yīng)寫上#include<reg51.h>或#include“reg51.h”。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例1、頭文件例如:sbitEA=IE^7;或sbitEA=0xAF;(有一些頭文件也這樣書寫,0xAF是IE寄存器中的最高位的地址,與IE^7的寫法作用相同)把IE這個(gè)寄存器中的最高位重新命名為EA,以后單獨(dú)操作EA即可。本例中的TMOD、TH0、TL0、TR0四個(gè)名稱之所以能在程序中代表相關(guān)寄存器來使用,就是因?yàn)樗鼈円呀?jīng)在頭文件中進(jìn)行了聲明。注意:在應(yīng)用時(shí),如果將大寫的TMOD或EA寫成小寫的tmod或ea,編譯程序時(shí)將會(huì)出錯(cuò),找不到tmod或ea,因?yàn)樵陬^文件中定義的是“sfrTMOD=0x89;”“sbitEA=IE^7;”都是大寫的,這也是大多數(shù)初學(xué)者開始編寫程序時(shí)容易犯的錯(cuò)誤。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例2、主函數(shù)main()一個(gè)沒有返回值,沒有參數(shù)的函數(shù)。格式:voidmain()或voidmain(void)說明:(1)任何一個(gè)C程序中可以包含一個(gè)或多個(gè)函數(shù),其中必須包含main函數(shù)(且只能有一個(gè)),本例中只有一個(gè)函數(shù)main(),它是整個(gè)程序開始執(zhí)行的入口,所有的單片機(jī)在運(yùn)行程序時(shí),總是從主函數(shù)開始運(yùn)行的。(2)無返回值的函數(shù):main()是一個(gè)無返回值的函數(shù),其前面的void表示無返回值的意思(void可省略不寫),該函數(shù)執(zhí)行完后不返回任何值。(3)無參數(shù)的函數(shù):main()是一個(gè)無參數(shù)的函數(shù),表示該函數(shù)不帶任何參數(shù),即main后面的括號(hào)中沒有任何參數(shù),括號(hào)中是空的或void。(4)在main()之后有兩個(gè)大括號(hào){},程序中所有的代碼都寫在兩個(gè)大括號(hào)內(nèi),代碼中的每條語句后都要加上分號(hào),語句與語句之間可以用空格或回車隔開。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)計(jì)舉例3、注釋注釋有兩種寫法:(1)∥……只能注釋一行,當(dāng)換行時(shí),需要在新行上重新寫兩個(gè)斜扛進(jìn)行注釋。(2)/*…*/可以注釋任意行,即斜扛星號(hào)與星號(hào)斜扛之間的所有文字都作為注釋。所有注釋都不參與程序編譯,編譯器在編譯過程中會(huì)自動(dòng)刪除注釋,一般在編寫較大的程序時(shí)都應(yīng)加上注釋,這樣,以后當(dāng)我們?cè)俅巫x程序時(shí),因?yàn)橛辛俗⑨?,其代碼的意義便一目了然了。若無注釋,我們不得不將程序重新閱讀一遍方可知道代碼含義。10.2C51程序設(shè)計(jì)10.2.1定時(shí)/計(jì)數(shù)器初始化程序設(shè)10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序?qū)崿F(xiàn)流水燈,可以用移位操作來實(shí)現(xiàn),也可以用C51自帶的函數(shù)來實(shí)現(xiàn)。1、循環(huán)移位操作在10.1節(jié)中我們介紹了移位運(yùn)算符,這里我們來學(xué)習(xí)循環(huán)移位操作。(1)循環(huán)右移被操作數(shù)的各位依次向右移動(dòng)一位,其中,最低位移入最高位。C語言中沒有專門的循環(huán)右移位運(yùn)算符,我們可以利用右移位運(yùn)算符編寫程序?qū)崿F(xiàn)循環(huán)右移位,或直接利用C51中自帶的庫函數(shù)_cror_來實(shí)現(xiàn)。循環(huán)右移位操作,如圖10-3所示。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序【例10-2】編寫程序?qū)崿F(xiàn)如下功能,使變量t中的值循環(huán)右移位。#include<reg51.h>//包含頭文件unsignedchart;//定義無符號(hào)字符類型變量tvoidmain()//主函數(shù){t=0x66;//給t賦初始值while(1)//循環(huán)程序,每次循環(huán)使t中的當(dāng)前值左移1位{t=t>>1;}}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序(2)循環(huán)左移
被操作數(shù)的各位依次向左移動(dòng)一位,其中,最高位移入最低位。C語言中沒有專門的循環(huán)左移位運(yùn)算符,我們可以利用左移位運(yùn)算符編寫程序?qū)崿F(xiàn)循環(huán)左移,或直接利用C51庫中自帶的函數(shù)_crol_來實(shí)現(xiàn)。循環(huán)左移位操作,如圖10-4所示。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序【例10-3】編寫程序?qū)崿F(xiàn)如下功能,使變量t中的值循環(huán)左移位。#include<reg51h>//包含頭文件unsignedchart;//定義無符號(hào)字符類型變量tvoidmain()//主函數(shù){t=0x55;//給t賦初始值while(1)//循環(huán)程序,每次循環(huán)使t中的當(dāng)前值左移1位{t=t<<1;}}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序2、移位函數(shù)_crol_介紹大家打開Keil軟件安裝文件夾,定位到Keil\C51\HLP文件夾,打開此文件夾下的C51lib文件,這是C51自帶庫函數(shù)幫助文件。在索引欄我們找到_crol_函數(shù),雙擊打開它的介紹,內(nèi)容如下:#include<intrins.h>unsignedchar_crol_(unsignedcharc,/*charactertorotateleft*/unsignedcharb);/*bitpositionstorotate*/10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序2、移位函數(shù)_crol_介紹大家打開Keil軟件安裝文件夾,定位到Keil\C51\HLP文件夾,打開此文件夾下的C51lib文件,這是C51自帶庫函數(shù)幫助文件。在索引欄我們找到_crol_函數(shù),雙擊打開它的介紹,內(nèi)容如下:#include<intrins.h>unsignedchar_crol_(unsignedcharc,/*charactertorotateleft*/unsignedcharb);/*bitpositionstorotate*/函數(shù)_crol_是C51自帶的內(nèi)部庫函數(shù),在使用這個(gè)函數(shù)之前,需要在程序開頭包含它所在的頭文件(即#include<intrins.h>)。_crol_是一個(gè)有返回值、帶參數(shù)的函數(shù),其功能是將字符c循環(huán)左移b位同時(shí)將左移之后的值返回。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序【例10-4】編程實(shí)現(xiàn)如下功能,將變量a中的二進(jìn)制值向左移3位。#include<intrins.h>//包含頭文件voidmain(){chara;//定義字符類型的變量acharb;//定義字符類型的變量ba=0xA5;//給a賦初始值b=_crol_(a,3);/*移位后的值返回給b故b=0x2D*/}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序3、流水燈程序的實(shí)現(xiàn)【例10-5】參考第二章的圖2-12,利用C51自帶的庫函數(shù)_crol_,每隔300ms依次點(diǎn)亮發(fā)光二級(jí)管,實(shí)現(xiàn)流水燈的程序。通過本例我們將對(duì)#define宏定義、循環(huán)語句for和while、自定義子函數(shù)等三個(gè)方面知識(shí)進(jìn)行講解。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序3、流水燈程序的實(shí)現(xiàn)程序代碼如下所示:#include<reg51.h> //包含頭文件#include<intrins.h>#defineucharunsignedchar//宏定義#defineuintunsignedint voiddelay(uint); //聲明子函數(shù)uchart;10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序3、流水燈程序的實(shí)現(xiàn)程序代碼如下所示:voidmain() //主函數(shù){t=0xfe; //給t賦初值11111110while(1) //循環(huán)點(diǎn)亮發(fā)光二級(jí)管{P1=t;delay(300);//延時(shí)300毫秒t=_crol_(t,1);//將t循環(huán)左移1位后再賦給t} }voiddelay(uintx)//延時(shí)1ms子函數(shù){uinti,j;for(i=x;i>0;i--) for(j=110;j>0;j--);}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序3、流水燈程序的實(shí)現(xiàn)對(duì)于程序中“t=_crol_(t,1);”語句,因?yàn)開crol_是一個(gè)帶返回值的函數(shù),本句在執(zhí)行時(shí),先執(zhí)行等號(hào)右邊的表達(dá)式,即將t的值循環(huán)左移一位,然后將結(jié)果再重新賦給t,如t初值為0xfe,二進(jìn)制為11111110,執(zhí)行此函數(shù)后值為11111101,即0xfd,然后再將0xfd重新賦給t變量,點(diǎn)亮第2個(gè)發(fā)光二級(jí)管,依次循環(huán)點(diǎn)亮后面的發(fā)光二極管。除這種方法實(shí)現(xiàn)流水燈外,利用左移、右移指令與邏輯運(yùn)算指令也可以實(shí)現(xiàn)循環(huán)移位,大家若感興趣可以自己編寫這方面的程序。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序4、#define宏定義(1)格式:#define新名稱原名稱注意后面沒有分號(hào),#define命令可以解釋為給“原名稱”重新起一個(gè)比較簡單的“新名禰”,方便以后在程序中直接使用簡短的新名稱,而不必每次都寫煩瑣的原名稱。(2)本例中我們使用宏定義的目的就是將unsignedint用uint代替,在上面的程序中可以看到,當(dāng)我們需要定義unsignedint型變量時(shí),并沒有寫“unsignedinti,j;”,取而代之的是“uinti,j;”,在一個(gè)程序代碼中,只要宏定義過一次,那么在整個(gè)代碼中都可以直接使用它的“新名稱”。注意,對(duì)同一個(gè)內(nèi)容,宏定義只能定義一次,若定義兩次,將會(huì)出現(xiàn)重復(fù)定義的錯(cuò)誤提示。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while(1)for語句格式:for(表達(dá)式1;表達(dá)式2;表達(dá)式3){語句}說明:對(duì)于{語句}大括號(hào)中的語句如果沒有,可以為空或不寫大括號(hào)。三個(gè)表達(dá)式之間必須用分號(hào)分隔。for語句執(zhí)行步驟:第1步:求解一次表達(dá)式1,設(shè)置初始條件,可以為0個(gè)、1個(gè)或多個(gè)變量賦初值。第2步,求解循環(huán)條件表達(dá)式2,若其值為真(非0即為真),則執(zhí)行for中語句,然后執(zhí)行第3步;否則結(jié)束for語句,直接跳出,不再執(zhí)行第3步。第3步,求解表達(dá)式3。第4步,跳到第2步重復(fù)執(zhí)行。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while延時(shí)時(shí)間:
for循環(huán)在本例題中的應(yīng)用是利用for語句(或while語句)經(jīng)過若干次循環(huán)以后,可以獲得所需的延時(shí)時(shí)間,下面就是用for語句來寫的一個(gè)簡單的延時(shí)程序段。unsignedintj;for(j=1;j<=200;j++);看上面這兩句,首先定義一個(gè)無符號(hào)整型變量j,之后,進(jìn)入for循環(huán),單片機(jī)在執(zhí)行for語句的時(shí)候是需要時(shí)間的,上面的延時(shí)程序段for語句重復(fù)執(zhí)行了200次,從而可以獲得一個(gè)延時(shí)時(shí)間,因此,我們就可以利用單片機(jī)執(zhí)行for循環(huán)(或其他循環(huán)語句)來獲得延時(shí)時(shí)間。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while在語句for(j=1;j<=200;j++);中如果我們將j<=200改為j<=65536想獲得更大的延時(shí)時(shí)間,那么程序運(yùn)行時(shí)將會(huì)出現(xiàn)問題,為什么呢?因?yàn)閖是一個(gè)無符號(hào)整數(shù)其最大的值為65535,所以,程序運(yùn)行后就會(huì)出現(xiàn)問題,將達(dá)不到我們所需要的時(shí)間。這是很多初學(xué)者最容易犯的錯(cuò)誤。因此我們尤其要注意,在使用變量時(shí)首先要考慮變量類型,然后根據(jù)變量類型賦一個(gè)合理的值。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while那么,怎樣才能通過for語句寫出更長的延時(shí)時(shí)間呢?在下例中所使用的兩層嵌套for語句即可獲得。uinti,j;for(i=x;i>0;i--) for(j=100;j>0;j--);第一個(gè)for后面沒有分號(hào),那么編譯器默認(rèn)第二個(gè)for語句就是第一個(gè)for語句的內(nèi)部語句,而第二個(gè)for語句內(nèi)部語句為空,程序在執(zhí)行時(shí),第一個(gè)for語句中的i每減一次,第二個(gè)for語句便執(zhí)行100次,因此上面這個(gè)例子便相當(dāng)于共執(zhí)行了110×x次for語句。通過這種嵌套我們便可以獲得較長的時(shí)間延時(shí),我們還可以進(jìn)行更多層的嵌套來增加延時(shí)時(shí)間,或是改變變量類型等來增加執(zhí)行時(shí)間。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while在C語言中這種延時(shí)語句不好算出它的精確時(shí)間,如果需要非常精確的延時(shí)時(shí)間,我們?cè)谇懊嬷v到利用單片機(jī)內(nèi)部的定時(shí)器來延時(shí),它的精度非常高,可以精確到微秒級(jí)。而一般的簡單延時(shí)語句實(shí)際上我們并不需要太精確。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序5、循環(huán)語句for和while(2)while語句介紹格式:while(表達(dá)式){語句}特點(diǎn):先判斷表達(dá)式,后執(zhí)行內(nèi)部語句。原則:若表達(dá)式為真,那么執(zhí)行內(nèi)部語句。否則跳出while語句,執(zhí)行后面的語句。需要注意如下的三點(diǎn):在C語言中我們一般把“0”認(rèn)為是“假”,“非0”認(rèn)為是“真”,也就是說,只要不是0就是真,所以,非0的數(shù)都是真。{語句}中的語句部分可以是語句塊,也可以為空,就是說“while(1){};”或“while(1);”也正確,但分號(hào)“;”一定不能少,否則while()會(huì)把跟在它后面第一個(gè)分號(hào)前的語句認(rèn)為是它的內(nèi)部語句;10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序例如:while(1)P0=11;P1=22;…上面這個(gè)例子中,while()會(huì)把“P0=11;”當(dāng)做它的語句,即使這條語句并沒有加大括號(hào)。因此,以后在寫程序時(shí),如果while()內(nèi)部只有一條語句,我們就可以省去大括號(hào),而直接將這條語句跟在它的后面。例如:while(1)P0=11;10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序表達(dá)式可以是一個(gè)常數(shù)、一個(gè)運(yùn)算或一個(gè)帶返回值的函數(shù)。在本例中使用while語句我們將不停地循環(huán)點(diǎn)亮發(fā)光二級(jí)管,因?yàn)樵谡Z句while(1)中的條件是1,非0即為真,條件永遠(yuǎn)為真,因此只要程序運(yùn)行,發(fā)光二級(jí)管將不停地被依次循環(huán)點(diǎn)亮。初學(xué)者可能會(huì)這樣想,我讓單片機(jī)把發(fā)光二極管點(diǎn)亮后,就讓它停止工作,不再執(zhí)行別的指令,這樣不是更好嗎?請(qǐng)大家注意,單片機(jī)是不能停止工作的,只要它有電,有晶振在起振,它就不會(huì)停止工作,每過一個(gè)機(jī)器周期,它內(nèi)部的程序指針就要加1,程序指針就指向下一條要執(zhí)行的指令。想讓它停止工作的辦法就是把電斷掉.不過這樣發(fā)光二極管也就不會(huì)亮了。不過我們可以將單片機(jī)設(shè)置為休眠狀態(tài)或掉電模式,這樣可以最大限度地降低它的功耗。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序6、自定義子函數(shù)在C語言中,除了系統(tǒng)自帶的庫函數(shù)比如求平方根函數(shù)sqrt、求絕對(duì)值函數(shù)fabs以及上例中用到的移位函數(shù)_crol_等外,用戶也可以根據(jù)編程需要自定義一些子函數(shù),比如有一些程序段不止一次要被用到,為了不重復(fù)編寫相同代碼,我們就可以把這樣的程序段寫成一個(gè)子函數(shù),當(dāng)在主函數(shù)或其他函數(shù)中需要用到這個(gè)程序段時(shí),直接調(diào)用這個(gè)子函數(shù)就可以了。C語言中的自定義子函數(shù)(從帶參數(shù)與否的角度)主要分為有兩種:不帶參數(shù)的自定義子函數(shù)帶參數(shù)的自定義子函數(shù)。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序6、自定義子函數(shù)(1)不帶參數(shù)子函數(shù)的定義、聲明及調(diào)用不帶參數(shù)子函數(shù)的定義:我們以下面這個(gè)程序?yàn)槔簐oiddelay(){for(i=100;i>0;i--)for(j=200;j>0;j--);}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序其中,void表示這個(gè)函數(shù)執(zhí)行完后不返回任何數(shù)據(jù),即它是一個(gè)無返回值的函數(shù)。delay是函數(shù)名,這個(gè)名字只要符合C語言標(biāo)識(shí)符的命名規(guī)則即可,但是注意不要和C語言中的關(guān)鍵字相同。一般我們寫成方便記憶或讀懂的名字,也就是一看到函數(shù)名就知道此函數(shù)實(shí)現(xiàn)的內(nèi)容是什么。在這里寫成delay這個(gè)函數(shù)是一個(gè)延時(shí)子函數(shù)。緊跟函數(shù)名后面的是一個(gè)括號(hào),這個(gè)括號(hào)里沒有任何數(shù)據(jù)或符號(hào)(即C語言當(dāng)中的“參數(shù)”),因此,這個(gè)函數(shù)是一個(gè)無參數(shù)的函數(shù)。接下來兩個(gè)大括號(hào)中包含著其他要實(shí)現(xiàn)的語句。以上講解的是一個(gè)無返回值、不帶參數(shù)的函數(shù)的定義。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序不帶參數(shù)子函數(shù)的聲明:聲明子函數(shù)的目的是為了編譯器在編譯主程序的時(shí)候,當(dāng)它遇到一個(gè)子函數(shù)時(shí)知道有這樣一個(gè)子函數(shù)存在,并且知道它的類型和帶參情況等信息,以方便為這個(gè)子函數(shù)分配必要的存儲(chǔ)空間。子函數(shù)可以寫在調(diào)用函數(shù)(比如main()函數(shù))的前面或后面。當(dāng)寫在main()函數(shù)后面時(shí),必須要在調(diào)用函數(shù)之前聲明子函數(shù),聲明方法如下:將返回值特性、函數(shù)名及后面的小括號(hào)完全復(fù)制,無參函數(shù),則小括號(hào)內(nèi)為空。最后在小括號(hào)的后面必須加上分號(hào)“;”。當(dāng)寫在main()函數(shù)前面時(shí),不需要聲明,因?yàn)閷懞瘮?shù)體的同時(shí)就已經(jīng)相當(dāng)于聲明了函數(shù)本身。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序不帶參數(shù)子函數(shù)的調(diào)用:函數(shù)名();10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序【例10-6】編程實(shí)現(xiàn)在主函數(shù)中調(diào)用延時(shí)子程序,從而獲得一定的延時(shí)時(shí)間。#include<reg51.h>//包含頭文件#defineuintunsignedint//宏定義voiddelay();//子函數(shù)聲明voidmain(){…delay();//子函數(shù)調(diào)用
…
}voiddelay()//延時(shí)子函數(shù)定義 {uinti,j;for(i=500;i>0;i--) for(j=110;j>0;j--);}10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序本例中,我們注意到“uinti,j;”語句,i和j兩個(gè)變量的定義放到了子函數(shù)里,而沒有寫在所有函數(shù)的最外面。在函數(shù)外面定義的變量叫做全局變量;在某個(gè)函數(shù)內(nèi)部定義的變量叫做局部變量,這里i和j就是局部變量。注意:局部變量只在當(dāng)前函數(shù)中有效,程序一旦執(zhí)行完當(dāng)前函數(shù),在它內(nèi)部定義的所有變量都將自動(dòng)銷毀,當(dāng)下次再調(diào)用該函數(shù)時(shí),編譯器重新為其分配內(nèi)存空間。我們要知道.在一個(gè)程序中,每個(gè)全局變量都占據(jù)著單片機(jī)內(nèi)固定的RAM單元,局部變量是用時(shí)隨時(shí)分配,不用時(shí)立即銷毀。一個(gè)單片機(jī)的RAM是有限的,如8051只有128B的RAM,如果要定義unsignedchar型變量的話,我們最多只能定義128個(gè)。很多時(shí)候,當(dāng)寫一個(gè)比較大的程序時(shí),經(jīng)常會(huì)遇到內(nèi)存不夠用的情況,因此我們從一開始寫程序時(shí)就要堅(jiān)持能用局部變量就不用全局變量的原則,以節(jié)省內(nèi)存空間。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序(2)帶參數(shù)子函數(shù)的定義、聲明及調(diào)用帶參數(shù)子函數(shù)的定義:【例10-5】中voiddelay(uintx)是延時(shí)1ms的帶參數(shù)子函數(shù),其定義如程序中所示。帶參數(shù)子函數(shù)的聲明:因delay寫在了被調(diào)用函數(shù)main()的后面,所以,需在前面進(jìn)行函數(shù)聲明。聲明時(shí)必須將參數(shù)類型帶上,如果有多個(gè)參數(shù),多個(gè)參數(shù)類型都要寫上,類型后面可以不跟變量名.也可以寫上變量名。帶參數(shù)子函數(shù)的調(diào)用:10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈程序(2)帶參數(shù)子函數(shù)的定義、聲明及調(diào)用本例中delay后面的括號(hào)中多了一句“uintx”,x就是這個(gè)子函數(shù)所帶的參數(shù),它是一個(gè)unsignedint型變量,又叫做這個(gè)函數(shù)的形參,當(dāng)進(jìn)行函數(shù)調(diào)用時(shí)我們用一個(gè)具體真實(shí)的數(shù)據(jù)代替這個(gè)形參,這個(gè)真實(shí)數(shù)據(jù)被稱為實(shí)參,形參被實(shí)參代替之后,在子函數(shù)內(nèi)部所有和形參名相同的變量將都被實(shí)參代替。有了這種帶參函數(shù),我們要調(diào)用一個(gè)延時(shí)300ms的函數(shù)就可以寫成“delay(300);”,要延時(shí)200ms可以寫成“delay(200);”,十分方便。10.2C51程序設(shè)計(jì)10.2.2點(diǎn)亮發(fā)光二極管實(shí)現(xiàn)流水燈10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例【例10-7】用C51編程實(shí)現(xiàn)【例5-3】的功能程序代碼如下所示:#include<reg51.h>//包含頭文件sbitCINT0=P3^0; //聲明清除中斷的引腳voiddelay(unsignedinti);//delay函數(shù)聲明unsignedchararr[100];//聲明數(shù)組用于存儲(chǔ)外設(shè)數(shù)據(jù),容量為100,可變unsignedinta;//定義無符號(hào)整型變量a10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例voidmain(void){CINT0=0;//清除INT0時(shí)提供負(fù)脈沖IT0=0;//低電平觸發(fā)外部中斷0EX0=1; //允許外部中斷0EA=1;//CPU開中斷a=0;while(1){
…}10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例//INT0中斷服務(wù)程序voidcounter0(void)interrupt0{CINT0=1;//不清除INT0時(shí)提供負(fù)脈沖delay(100);//調(diào)用延時(shí)子程序CINT0=0;//清除INT0時(shí)提供負(fù)脈沖arr[a]=P1;//將數(shù)據(jù)存入數(shù)組delay(100);//調(diào)用延時(shí)子程序a++;}10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例voiddelay(unsignedinti)//定義延時(shí)子程序{charj;for(i;i>0;i--)for(j=200;j>0;j--);}10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例說明:C51的中斷函數(shù)格式如下:void函數(shù)名()interrupt中斷號(hào)[using工作組]{中斷服務(wù)程序代碼}其中:函數(shù)名前有void,中斷函數(shù)不返回任何值。函數(shù)名按C語言標(biāo)識(shí)符來起,但不要與C語言中的關(guān)鍵字相同。函數(shù)名后面的括號(hào)是空的,中斷函數(shù)不帶任何的參數(shù)。10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例中斷號(hào)是指單片機(jī)的幾個(gè)中斷源的序號(hào),如下表所示10-5,本例中所使用的是外部中斷0所以中斷號(hào)為0。using工作組,可選,確定中斷函數(shù)使用單片機(jī)內(nèi)存中4組工作寄存器中的哪一組,C51編譯器在編譯程序時(shí)會(huì)自動(dòng)分配工作組,因此,可以省略不寫。10.2C51程序設(shè)計(jì)10.2.3單個(gè)中斷系統(tǒng)設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例【例10-8】用C51編程實(shí)現(xiàn)【例6-4】的功能。程序代碼如下:#include<reg51.h>//包含頭文件sbitWORK=P1^0;//WORK為1時(shí)包裝機(jī)工作/*系統(tǒng)初始化子函數(shù)*/voidsystem_Ini(){TMOD=0x06;//置T0工作于計(jì)數(shù)模式2TH0=0xE8; //裝入計(jì)數(shù)初值TL0=0xE8; ET0=1;//T0開中斷EA=1; //CPU開中斷TR0=1; //啟動(dòng)T0}10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例/*延時(shí)子函數(shù)*/voiddelay(unsignedinti){charj;for(i;i>0;i--)for(j=200;j>0;j--);}/*主函數(shù)*/voidmain(){system_Ini() ;//系統(tǒng)初始化while(1){
….}}10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例/*定時(shí)計(jì)數(shù)器0的中斷函數(shù)*/voidT0zd(void)interrupt1{TH0=0xE8;//給定時(shí)器T0賦初始值TL0=0xE8;WORK=1; //包裝機(jī)工作delay(100);//延時(shí)WORK=0;//包裝機(jī)停止工作}10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例說明:(1)voiddelay(unsignedinti)的定義出現(xiàn)在了被調(diào)用函數(shù)voidT0zd(void)interrupt1的前面,所以不需要聲明,同樣,voidsystem_Ini()的定義在main前面,所以也不需要聲明。(2)voidT0zd(void)interrupt1,序號(hào)為1即定時(shí)器0的中斷服務(wù)程序。10.2C51程序設(shè)計(jì)10.2.4定時(shí)器程序設(shè)計(jì)舉例10.2C51程序設(shè)計(jì)10.2.5串行通信程序設(shè)計(jì)舉例【例10-9】用C51編程實(shí)現(xiàn)【例7-2】的功能程序代碼如下:#include<reg51.h>//包含頭文件#include<intrins.h>#defineucharunsignedchar#define
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《管理會(huì)計(jì) 第3版》 課件 第01章 管理會(huì)計(jì)概述
- 微積分 第3版 課件 7第七節(jié) 二重積分
- 高考語文真題分類卷-專題六 文學(xué)類文本閱讀(含答案)
- 動(dòng)物之最課件教學(xué)課件
- 網(wǎng)絡(luò)接入?yún)f(xié)議書(2篇)
- 黨群服務(wù)中心建設(shè)工作總結(jié)匯報(bào)
- 南京航空航天大學(xué)《薄膜材料與技術(shù)》2022-2023學(xué)年第一學(xué)期期末試卷
- 南京工業(yè)大學(xué)浦江學(xué)院《食品工藝學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 富陽佳苑4#樓施工組織設(shè)計(jì)
- 南京工業(yè)大學(xué)浦江學(xué)院《混凝土結(jié)構(gòu)基本原理課程設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 土砂石料廠項(xiàng)目融資計(jì)劃書
- 2024年給藥錯(cuò)誤護(hù)理不良事件分析持續(xù)改進(jìn)
- 國際貿(mào)易法與跨境業(yè)務(wù)合規(guī)的風(fēng)險(xiǎn)管理與應(yīng)對(duì)策略
- 麻醉科臨床診療指南2020版
- 供應(yīng)商QSA-QPA評(píng)鑒表
- 【行政管理社會(huì)調(diào)查計(jì)劃+調(diào)查記錄表+調(diào)查報(bào)告5600字】
- 餐券模板完整
- 三查四定表完整版本
- (完整文本版)貨物驗(yàn)收單
- 江蘇省南通市海門區(qū)多校2023-2024學(xué)年上學(xué)期期中聯(lián)考八年級(jí)數(shù)學(xué)試卷
- 人教版九年級(jí)道德與法治 上冊(cè) 第三單元《文明與家園》大單元整體教學(xué)設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論