計算機(jī)控制技術(shù)西電版PPT第2章單片機(jī)C語言編程_第1頁
計算機(jī)控制技術(shù)西電版PPT第2章單片機(jī)C語言編程_第2頁
計算機(jī)控制技術(shù)西電版PPT第2章單片機(jī)C語言編程_第3頁
計算機(jī)控制技術(shù)西電版PPT第2章單片機(jī)C語言編程_第4頁
計算機(jī)控制技術(shù)西電版PPT第2章單片機(jī)C語言編程_第5頁
已閱讀5頁,還剩51頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、補(bǔ)充知識 2.1 概述 2.2 C51程序結(jié)構(gòu) 2.3 C51的數(shù)據(jù)類型與運(yùn)算符 2.4 C51的函數(shù) 2.5 C51的硬件編程 51系列單片機(jī)支持三種高級語言,即PL/M,C和BASIC。 C語言是一種通用的程序設(shè)計語言,其代碼率高,數(shù)據(jù)類型及運(yùn)算符豐富,并具有良好的程序結(jié)構(gòu),適用于各種應(yīng)用的程序設(shè)計,是目前使用較廣的單片機(jī)編程語言。 MCS-51系列單片機(jī)采用的C語言 ,簡稱C51。 C51符合C語言的ANSI標(biāo)準(zhǔn),并根據(jù)單片機(jī)的特性進(jìn)行了擴(kuò)展。 C51所產(chǎn)生的目標(biāo)代碼短、運(yùn)行速度高、所需存儲空間小。注:注:1.1.在實(shí)際的系統(tǒng)設(shè)計中,當(dāng)設(shè)計對象只是一個小的嵌入式系統(tǒng)時,匯編在實(shí)際的系統(tǒng)設(shè)

2、計中,當(dāng)設(shè)計對象只是一個小的嵌入式系統(tǒng)時,匯編語言是一個很好的選擇,因?yàn)榇a一般都不超過語言是一個很好的選擇,因?yàn)榇a一般都不超過8K8K,而且都比較簡單;,而且都比較簡單; 2. 2.當(dāng)一個系統(tǒng)對時鐘要求很嚴(yán)格時,使用匯編語言成了唯一的方法。當(dāng)一個系統(tǒng)對時鐘要求很嚴(yán)格時,使用匯編語言成了唯一的方法。 同ANSI C一樣,C51的程序由一個個函數(shù)組成,這里的函數(shù)和其他語言的“子程序”或“過程 ”具有相同的意義。 必須有一個主函數(shù)main(),程序的執(zhí)行從main()函數(shù)開始,調(diào)用其他函數(shù)后返回主函數(shù)main(),最后在主函數(shù)中結(jié)束整個程序而不管函數(shù)的排列順序如何。 功能函數(shù)可以是C51語言提供

3、的庫函數(shù),也可以是用戶自定義的函數(shù)。組成結(jié)構(gòu):預(yù)處理語句預(yù)處理語句全局變量說明全局變量說明 /*可被各函數(shù)引用*/ main() main() /*主函數(shù)*/ 局部變量說明局部變量說明 /*只在本函數(shù)引用*/執(zhí)行語句執(zhí)行語句( (包括函數(shù)調(diào)用語句包括函數(shù)調(diào)用語句) ) fun1(fun1(形式參數(shù)表形式參數(shù)表) ) /*函數(shù)1*/ 形式參數(shù)說明形式參數(shù)說明 局部變量說明局部變量說明 執(zhí)行語句執(zhí)行語句( (包括調(diào)用其他函數(shù)語句包括調(diào)用其他函數(shù)語句) ) funn(funn(形式參數(shù)表形式參數(shù)表) ) /*函數(shù)n*/形式參數(shù)說明形式參數(shù)說明 局部變量說明局部變量說明 執(zhí)行語句執(zhí)行語句 C語言的語句

4、規(guī)則: 1. 每個變量必須先說明后引用,變量名英文大小寫是有差別的。 2. C語言程序一行可以書寫多條語句,但每個語句必須以“;”結(jié)尾,一個語句也可以多行書寫。 3. C語言的注釋用/*/或/表示。 4. “”花括號必須成對,位置隨意,可在緊挨函數(shù)名后,也可另起一行,多個花括號可以同行書寫,也可逐行書寫,為層次分明,增加可讀性,同一層的“”花括號對齊,采用逐層縮進(jìn)方式書寫。 51系列單片機(jī)的內(nèi)存區(qū)域被分為兩大類。一類是程序存儲區(qū),即ROM;另一類是數(shù)據(jù)存儲區(qū),包括內(nèi)部數(shù)據(jù)存儲區(qū)和外部數(shù)據(jù)存儲區(qū)。內(nèi)部數(shù)據(jù)存儲區(qū)中又包含了51單片機(jī)的特殊功能寄存器。1 數(shù)據(jù)存儲區(qū) 1) 內(nèi)部數(shù)據(jù)存儲區(qū) data

5、idata bdata 2) 外部數(shù)據(jù)存儲區(qū) xdata pdata2 程序存儲器 code存儲類型存儲類型存儲位置存儲位置 位位 數(shù)數(shù) 范圍范圍DATADATA直接尋址片內(nèi)直接尋址片內(nèi)RAMRAM的的00007FH7FH地址地址8 80 0127127BDATABDATA片內(nèi)片內(nèi)RAMRAM的可位尋址的可位尋址20202FH2FH地址地址8 8、1 10 0127127(位)(位)IDATAIDATA間接尋址片內(nèi)間接尋址片內(nèi)RAMRAM的的0000FFHFFH地址地址8 80 0255255PDATAPDATA尋址外部尋址外部RAMRAM,使用指令,使用指令MOVX A,MOVX A,RiR

6、i8 80 0255255XDATAXDATA使用使用DPTR DPTR 尋址外部尋址外部RAMRAM16160 06553565535CODECODE使用使用DPTR DPTR 尋址程序存儲器尋址程序存儲器16160 065535655355151系列系列單單片機(jī)的存片機(jī)的存儲區(qū)類儲區(qū)類型型 無論哪種數(shù)據(jù)都是存放在存貯單元中的,每一個數(shù)據(jù)究竟要占用幾個單元(即數(shù)據(jù)的長度)都要提供給編譯系統(tǒng),編譯系統(tǒng)以此為根據(jù)預(yù)留存貯單元,這就是定義數(shù)據(jù)類型的意義。C51支持ANSI C的所有標(biāo)準(zhǔn)數(shù)據(jù)類型,并在此基礎(chǔ)上增設(shè)了位型及特殊功能寄存器類型。1. C51的數(shù)據(jù)類型2. 常量與變量C51支持的數(shù)據(jù)有常量

7、、變量、指針。 存儲時先高后低原則; 常量位置與定義說明有關(guān),一般放在程序存儲區(qū)code 。1)常量 整型常量、實(shí)型常量、字符常量、字符串常量、符號常量。 符號常量在使用前必須先定義,格式為: #define 標(biāo)識符 常量 /是C51的預(yù)處理指令2)變量 定義變量的一般格式: 存儲模式 數(shù)據(jù)類型 存儲器類型 變量名;char var; /*字符變量var,存儲類型由編譯模式確定*/ char code MSG =PARAMETER:;/*字符數(shù)組MSG 定位在程序存貯區(qū)*/unsigned long xdata array100; /*無符號長型數(shù)組定位在片外RAM區(qū),每元素占4bytes*/

8、 float idata x,y,z; /*實(shí)型變量x,y,z,定位在片內(nèi)用間址訪問的內(nèi)部RAM區(qū)*/bit lock; /*位變量Lock,由編譯器定位*/unsigned int pdata sion;/*無符號整型變量sion定位在外部RAM*/unsigned char xdata vector10 4 4 /*無符號字符型三維數(shù)組, 定位在片外RAM區(qū)*/sfr P0=0 x80; /*定義P0口,地址為80H*/char bdata flags; /*字符變量flags定位在可位尋址內(nèi)部RAM區(qū)*/ sbit flag0=flags0; /*定義flag0為flags.0 */ 說

9、明: 1. 字符型(char)、整型(int)和長整型(long)均有符號型(signed)和無符號型(unsigned)兩種,如果不是必須,盡可能選擇unsigned型,這將會使編譯器省卻符號位的檢測,使生成的程序代碼比signed類型短得多。 2. 程序編譯時,C51編譯器會自動進(jìn)行類型轉(zhuǎn)換,當(dāng)運(yùn)算符兩邊為不同類型的數(shù)據(jù)時,編譯器先將低級的數(shù)據(jù)類型轉(zhuǎn)換為較高級的數(shù)據(jù)類型,運(yùn)算后,運(yùn)算結(jié)果為高級數(shù)據(jù)類型。 3. bit和sbit都是C51擴(kuò)展的變量類型。bit用來定義一個普通位變量(0或1),編譯器在編譯過程中分配地址,除非指定否則這個地址隨機(jī)分布在整個可尋址空間中。所有可位尋址的位都可由s

10、bit指定,這包括可位尋址區(qū)和SFR中的位。 4.如果在變量說明時略去存貯器類型標(biāo)志符,編譯器會自動選擇默認(rèn)的存貯器類型。(1)關(guān)于指針型變量 在匯編語言程序中,要取存貯單元m的內(nèi)容可用直接尋址方式,也可用寄存器間接尋址方式 。如果用R1寄存器指示m的地址,則用R1取m單元的內(nèi)容。相對應(yīng)的在C語言中用變量名表示取變量的值(相當(dāng)于直接尋址),也可用另一個變量(如P)存放m的地址,P就相當(dāng)于R1寄存器 。用*P取得m單元的內(nèi)容(相當(dāng)于匯編的間接尋址方式)這里P即為指針型變量。下面表格表示兩種語言將m單元的內(nèi)容送n單元的對照語句。注:注: 上表省略了匯編語言程序中對符號地址上表省略了匯編語言程序中對

11、符號地址n和和m用用EQU偽指令進(jìn)行具體地址定義的偽指令進(jìn)行具體地址定義的 語句以及語句以及C語言對變量語言對變量n、m和指針變量和指針變量P進(jìn)行類型定義的語句,實(shí)際程序設(shè)計中,此進(jìn)行類型定義的語句,實(shí)際程序設(shè)計中,此步是不可步是不可 缺少的。表中缺少的。表中&為取地址運(yùn)算符,為取地址運(yùn)算符,*為取內(nèi)容運(yùn)算符。為取內(nèi)容運(yùn)算符。 匯編語言和匯編語言和C語言的對照語言的對照表表直接尋址間接尋址匯編語言C語言匯編語言C語言mov n,m傳送語句n=m;賦值語句mov R1,#m ;m的地址送R1 mov n,R1 ;m的內(nèi)容送nP=&m /*m的地址送P*/ n=*P /*m的內(nèi)容送n*/ 說明:

12、1. 在C語言中,為了能夠?qū)崿F(xiàn)直接對內(nèi)存單元進(jìn)行操作,引入了指針類型的數(shù)據(jù)。一個變量的地址就稱為該變量的指針。 2. 如果有一個變量專門用來存放另一個變量的地址,則稱之為指針變量。一個指針變量存放的內(nèi)容是另一個變量在內(nèi)存中的地址,每一個變量都有它自己的指針(地址)。 3. C語言中用“*”表示“指向”。 如:整型變量i的地址存放在指針變量ip中,則 i=0 x50; *ip=0 x50; 都是給同一個變量賦值。 4. 區(qū)分“&”和“*”運(yùn)算符。(2)指針型數(shù)據(jù)的類型 由于C51是結(jié)合51單片機(jī)硬件的,51單片機(jī)的不同存貯空間,有不同的地址范圍,即使對于同一外部數(shù)據(jù)存貯器,又有用Ri尋址(Ri為

13、八位)和用DPTR尋址(DPTR為十六位)兩種尋址方式,而指針本身也是一個變量,有它存放的存貯區(qū)和數(shù)據(jù)長度。因此,在指針類型的定義中要說明:被指的變量的數(shù)據(jù)類型和存貯類型;指針變量本身的數(shù)據(jù)類型(占幾個字節(jié))和存貯類型(即指針本身存放在什么存貯區(qū))。指針類型的定義形式如下: 數(shù)據(jù)類型 存儲器類型1 *存儲器類型2 標(biāo)識符; 指針類型指針類型(存存儲器類型儲器類型1)大小大小通用指針通用指針3 BytesXDATA 指針指針2 BytesCODE 指針指針2 BytesIDATA 指針指針1 ByteDATA 指針指針1 BytePDATA 指針指針1 ByteC51C51各類指針類型和其占用字

14、節(jié)大小各類指針類型和其占用字節(jié)大小 “存儲器類型存儲器類型2”2”選項(xiàng)用于指定指針本身的存儲器空間。選項(xiàng)用于指定指針本身的存儲器空間。指向不同存儲區(qū)變量的通用指針指針能適用于指向任何存貯空間,此時指針長度為3字節(jié),第一字節(jié)表示存貯器類型編碼,第二、三字節(jié)分別表示所指地址的高位和低位。unsigned char *ptr; /通用指針ptr,指針存放在默認(rèn)存儲區(qū)unsigned char * idata iptr ; /通用指針iptr,指針存放在idata存儲區(qū)指向固定存儲區(qū)變量的指針定義為data或idata,表示指針指向內(nèi)部數(shù)據(jù)存貯器;定義為pdata,表示指針指向外部數(shù)據(jù)存貯器,用Ri間

15、址。以上均為八位地址;定義為類型code/xdata,表示指針指向外部程序存貯器或外部數(shù)據(jù)存貯器指針,本身(即被指 示地址)應(yīng)為十六位長度。 int code *ptr; /指向code存儲區(qū)的指針ptr,指針存放在默認(rèn)存儲區(qū) int idata * pdata iptr; /指向idata存儲區(qū)的指針ptr,指針存放在pdata存儲區(qū) 指針變量說明:long xdata *px; /*指針px指向xdata區(qū)的long型 (每個數(shù)據(jù)占四個單元)變量,指針自身在編譯模式默認(rèn)的存貯區(qū),指針 長度為2個字節(jié)*/char xdata *data pd; /*指針pd指向xdata區(qū)的字符型變量,自身

16、在data區(qū),指針長度為2個字節(jié)*/data char xdata *pd; /*與上例等效*/ data int *pn; (和int *data pn及int*pn等效) /*定義一個類型為int 型的通用型指針,指針自身在data區(qū),長度為3字節(jié)*/ 在上例的指針聲明中包含如下幾個內(nèi)容: 1) 指針變量名(如px)前面冠以“*”,表示px為指針型變量,此處*不帶取內(nèi)容之意。 2) 指針指向的存貯類型,即指向哪個存貯區(qū),它決定了指針本身的長度(見數(shù)據(jù)類型表)。存貯類型聲明的位置在數(shù)據(jù)類型和指針名(如*px)之間,如無此項(xiàng)聲明,則此指針型變量為通用型。 3) 指針指向的存貯區(qū)的數(shù)據(jù)類型,即被

17、指向的存貯區(qū)以多少個單元作一個數(shù)據(jù)單位,當(dāng)程序通過指針對該區(qū)操作時,將按此規(guī)定的單元個數(shù)的內(nèi)容作為一個數(shù)據(jù)操作。 4) 指針變量自身的存貯類型,即指針處于什么區(qū)與自身的長度無關(guān),該聲明可位于聲明語句的開頭,也可在“*”和變量名之間。此項(xiàng)由編譯模式放在默認(rèn)區(qū),如無規(guī)定編譯模式,通常在data區(qū)。1. 特殊功能寄存器SFR定義 C51提供了一種自主形式的定義方式,使用特定關(guān)鍵字sfr 如 sfr SCON=0 x98; /*串行通信控制寄存器地址98H*/ sfr TMOD=0 x89; /*定時器模式控制寄存器地址89H*/ sfr ACC=0 xe0; /*A累加器地址E0H*/ sfr P1

18、=0 x90; /*P1端口地址90H*/ 定義了以后,程序中就可以直接引用寄存器名。 C51也建立了一個頭文件reg51.h (增強(qiáng)型為reg52.h),在該文件中對所有的特殊功能寄存器的進(jìn)行了sfr定義, 對特殊功能寄存器的有位名稱的可尋址位進(jìn)行了sbit定義,因此,只要用包含語句#include,就可以直接引用特殊功能寄存器名,或直接引用位名稱。要特別注意:在引用時特殊功能寄存器或者位名稱必須大寫。 sfr和sbit只能在函數(shù)外使用,一般放在程序的開頭。 2.對位變量的定義 C51對位變量的定義有三種方法: 將變量用bit類型的定義符定義為bit類型: 如 bit mn; mn為位變量,

19、其值只能是“0”或“1”,其位地址由C51任意分配。 采用字節(jié)尋址變量.位的方法: 如 int bdata ibase; /*ibase定義為整型變量*/ sbit mybit=ibase15;/*mybit定義為ibase的D15位*/ 這里位是運(yùn)算符“”相當(dāng)于匯編中的“.”,其后的最大取值依賴于該位所在的字節(jié)尋址變量的定義類型,如定義為char最大值只能為7。 對特殊功能寄存器的位的定義 方法1:使用頭文件及sbit定義符;多用于無位名的可尋址位。 例如 #include sbit P1_1=P11; /*P1_1為P1口的第1位*/ sbit ac=ACC7; /*ac定義為累加器A的第

20、7位*/方法2:使用頭文件reg51.h,再直接用位名稱。 例如 #include RS1=1; RS0=0; 方法3:字節(jié)地址位表示 例如 sbit CY=0 xd07;方法4:用位地址表示 例如 sbit CY=0 xd7; 方法5:用寄存器名.位定義 例如 sfr PSW=0 xd0; /*定義PSW地址為d0H*/ sbit CY=PSW7; /*CY為PSW.7*/ 3. C51對存貯器和外接I/O口的絕對地址訪問和定義 對存貯器的絕對地址訪問 利用絕對地址訪問的頭文件absacc.h可對不同的存貯區(qū)進(jìn)行訪問。該頭文件的函數(shù)有: CBYTE (訪問code區(qū)字符型) DBYTE (訪

21、問data區(qū)字符型) PBYTE (訪問pdata或I/O區(qū)字符型) XBYTE (訪問xdata或I/O區(qū)字符型) 還有CWORD、DWORD、PWORD和XWORD四個函數(shù),它們的訪問區(qū)域同上,只是訪問的類型為int型。例: #include #define com XBYTE0 x07ff 那么后面程序com變量出現(xiàn)的地方,就是對地址為07ffH的外部RAM或I/O口進(jìn)行訪問。 例: XWORD0=0 x9988; 即將9988H(int類型)送入外部RAM的0號和1號單元。 使用中要注意:absacc.h一定要包含進(jìn)程序, XWORD必須大寫。 對外部I/O口的訪問 由于單片機(jī)的I/O

22、口和外部RAM統(tǒng)一編址,因此對I/O口地址的訪問可用XBYTE (MOVX DPTR )或PBYTE (MOVX Ri)進(jìn)行。例: #include “absacc.h” #define PA XBYTE0 xffec /將PA定義為外部I/O口,地址0FFECH #define NAME DBYTE0 x40 /將NAME定義為片內(nèi)RAM,地址40H void main(void) PA=0 x3a; NAME=0 x01; 對絕對地址的定義定義變量時,使用_at_關(guān)鍵詞指定變量的絕對地址,格式為: 存儲類型 數(shù)據(jù)類型 變量名_at_ 絕對地址;例:data unsigned char x1

23、_at_ 0 x40; /在data區(qū)定義字節(jié)變量x1,它的地址為40H xdata unsigned int x2_at_ 0 x2000; /在xdata區(qū)定義字變量x2,它的地址為2000H void main(void) x1=0 xff; x2=0 x1234; #include void main(void)unsigned char code design=0 xFF,0 xFE,0 xFD,0 xFB,0 xF7,0 xEF,0 xDF,0 xBF,0 x7F,0 xBF,0 xDF,0 xEF,0 xF7,0 xFB,0 xFD,0 xFE;/定義花樣數(shù)據(jù),數(shù)據(jù)存放在片內(nèi)CO

24、DE區(qū)中unsigned int a; /定義延時用的變量unsigned char b; /定義循環(huán)用的變量unsigned char code * dsi; /定義指向CODE區(qū)的指針do dsi = &design0; /取得數(shù)組第一個單元的地址 for (b=0; b16; b+) for(a=0; a30000; a+); /延時一段時間 P1=*dsi; /從指針指向的地址取數(shù)據(jù)到P1口 dsi+; /指針加一 while(1); +5VP1.0P1.18751P1.2P1.71賦值運(yùn)算符: 將“”的右邊的值賦值給左邊的變量.2. C51的算術(shù)運(yùn)算符: (加或正號); (減或負(fù)號)

25、;* (乘號); / (除號); % (求余) 優(yōu)先級:先乘除,后加減,先括號內(nèi),再括號外3. C51的關(guān)系運(yùn)算符有六種: (小于); (大于); = (小于等于); = (大于等于); =(相等);!= (不相等) 優(yōu)先級:前四個高,后二個“=”和“!=”級別低。 4C51的邏輯運(yùn)算符有三種:&(邏輯與); |(邏輯或); !(邏輯非); 邏輯表達(dá)式和關(guān)系表達(dá)式的值相同,以0代表假,以1代表真。以上三種運(yùn)算的優(yōu)先級見圖。5C51的按位操作的運(yùn)算符有六種:&(按位與);(按位或); (按位異或); (位取反); (位右移 ) (注:補(bǔ)零移位)例1. a=0 xf0H; 表達(dá)式a=a值為0FH例

26、2. a=0 xea; 表達(dá)式a2值為A8H,即a值左移兩位,移位后空白 位補(bǔ)0。 6. 自增、自減運(yùn)算符: +i,-i (在使用i之前,先使i值加1,減1) i+,i- (在使用i之后,再使i值加1,減1) 例: 設(shè)i原值為5 j=+i 則j值為6,i值也為6 j=i+ 則j值為5,i值為6 ! (非)算術(shù)運(yùn)算關(guān)系運(yùn)算&和|= (賦值運(yùn)算)例2:P1.0接一開關(guān), P1.1接一發(fā)光二極管。開關(guān)打開時,二極管不亮,開關(guān)閉合時,二極管亮。 #include “reg51.h” sbit p1_0=P10; sbit p1_1=P11; void main( ) while(1) if (p1_0

27、=0) P1_1=0;else P1_1=1; +5V+5VP1.0P1.18751 C51程序由函數(shù)組成。 從用戶使用角度劃分,函數(shù)分為庫函數(shù)和用戶自定義函數(shù) 庫函數(shù)是編譯系統(tǒng)為用戶設(shè)計的一系列標(biāo)準(zhǔn)函數(shù),用戶只需調(diào)用,而無需自己去編寫這些復(fù)雜的函數(shù),如前面所用到的頭文件reg51.h等,有的頭文件中包括一系列函數(shù),要使用其中的函數(shù)必須先使用#include包含語句,然后才能調(diào)用。 用戶自定義函數(shù)是用戶根據(jù)任務(wù)編寫的函數(shù)。 從參數(shù)形式上函數(shù)分為無參函數(shù)和有參函數(shù)。 有參函數(shù)即是在調(diào)用時,調(diào)用函數(shù)用實(shí)際參數(shù)代替形式參數(shù),調(diào)用完返回結(jié)果給調(diào)用函數(shù)。 C51中函數(shù)的定義格式與標(biāo)準(zhǔn)C相似,增加了以下內(nèi)

28、容:1)將函數(shù)定義為中斷服務(wù)子程序;2)選擇函數(shù)所使用的寄存器體;3)選擇存儲模式;4)說明函數(shù)是一個可重入函數(shù)。 函數(shù)的定義格式: 返回值類型 函數(shù)名 (參數(shù)) 存儲模式 reentrant 1) 可省略 2) 返回值類型:無返回值時應(yīng)聲明為void;省略時默認(rèn)為int. 3)存儲模式:說明函數(shù)的存儲模式,可以為small、compact、large, 省略時 使用默認(rèn)的存儲模式。 4) reentrant:說明函數(shù)為可重入函數(shù),當(dāng)遞歸調(diào)用時使用此關(guān)鍵字。 中斷函數(shù)的定義格式:void 函數(shù)名 (void) interrupt n using m1)interrupt n:說明函數(shù)是中斷類型

29、n的中斷服務(wù)子程序C51編譯器支持32個中斷函數(shù),中斷類型號為031。函數(shù)定義為中斷函數(shù)后,編譯器會在對應(yīng)的中斷服務(wù)程序入口處, 生成 LJMP指令,直接跳到中斷函數(shù)。中斷函數(shù)不能帶參數(shù),不能定義函數(shù)返回值,且程序不能直接調(diào)用中斷函數(shù)。編譯器會自動為中斷函數(shù)添加保護(hù)現(xiàn)場的代碼,進(jìn)入函數(shù)后,壓棧保護(hù)函數(shù)中使用了的ACC、B、DPTR、PSW寄存器的值,返回前出棧恢復(fù)。編 號中 斷 源入 口 地 址0外部中斷00003H1定時器/計數(shù)器0000BH2外部中斷10013H3定時器/計數(shù)器1001BH4串行口中斷0023H5151單單片機(jī)的中片機(jī)的中斷斷源源編號編號2) using m:指定函數(shù)使用第

30、m個寄存器組,m可以為0、1、2、3,代表4個不同的工作寄存器組。定義函數(shù)時可省略using m選項(xiàng),此時編譯器自動選擇一個寄存器組作絕對寄存器組訪問;如定義則小心使用,要保證任何寄存器組的切換都只在控制的區(qū)域內(nèi)發(fā)生,否則產(chǎn)生不正確的函數(shù)結(jié)果。在函數(shù)的入口處將當(dāng)前工作寄存器組保護(hù)到堆棧中;函數(shù)退出之前將被保護(hù)的工作寄存器組從堆棧中恢復(fù)。函數(shù)調(diào)用的形式為:函數(shù)名( (實(shí)際參數(shù)表) ); 實(shí)參和形參必須在數(shù)目、類型及順序上嚴(yán)格保持一致, ,對于無參函數(shù)不存在實(shí)際參數(shù)表。函數(shù)的調(diào)用方式有三種: : 函數(shù)調(diào)用語句:即把被調(diào)函數(shù)名作為調(diào)用函數(shù)的一個語句,如fun1(); fun1(); 。 被調(diào)函數(shù)作為

31、表達(dá)式的運(yùn)算對象,如 result=2result=2* *get(a,b);get(a,b); 此時getget函數(shù)中的a,ba,b應(yīng)為實(shí)參,其以返回值參與式中的運(yùn)算。 被調(diào)函數(shù)作為另一個函數(shù)的實(shí)際參數(shù) 如 m=max(a,get(a,b)m=max(a,get(a,b);函數(shù)get(a,b)get(a,b)作為函數(shù)max()max()的一個實(shí)際參數(shù)。 注:1)1)如果被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之后,在主調(diào)函數(shù)前應(yīng)對被調(diào)函數(shù)進(jìn)行說明,形式為: 返回值類型 被調(diào)函數(shù)名( (形式參數(shù)表) ); 2)2)如果被調(diào)函數(shù)出現(xiàn)在主調(diào)函數(shù)之前,可以不對被調(diào)函數(shù)說明。下面以一個簡單例子來說明: int fun1

32、(a,b) int a,b; int c; c=a+b; return(c); main() int d,u=3,v=2; d=2*fun1(u,v); 上例被調(diào)函數(shù)在主調(diào)函數(shù)前,不用說明。 int fun1(a,b); main() int d,u=3,v=2; d=2*fun1(u,v); int fun1(a,b); int a,b; int c; c=a+b; return(c); 上例中被調(diào)函數(shù)在主調(diào)函數(shù)后,在前面對被調(diào)函數(shù)進(jìn)行說明。庫函數(shù) 是編譯系統(tǒng)為用戶設(shè)計的一系列標(biāo)準(zhǔn)函數(shù),用戶只需調(diào)用,而無需自己去編寫這些復(fù)雜的函數(shù),如前面所用到的頭文件reg51.h、absacc.h等,有的

33、頭文件中包括一系列函數(shù),要使用其中的函數(shù)必須先使用#include包含語句,然后才能調(diào)用。內(nèi)部庫函數(shù) #include _crol_, _cror_:將char型變量循環(huán)向左(右)移動指定位數(shù)后返回 _iror_, _irol_ :將int型變量循環(huán)向左(右)移動指定位數(shù)后返回 _lrol_, _lror_ :將long型變量循環(huán)向左(右)移動指定位數(shù)后返回 _nop_ :相當(dāng)于插入NOP _ testbit _ :相當(dāng)于JBC bitvar測試該位變量并跳轉(zhuǎn)同時清除2 直接訪問存儲區(qū)的頭文件include” 可以直接訪問指定地址的存儲區(qū)單元CBYTE、CWORD:直接訪問程序存儲區(qū);DBYT

34、E、DWORD:訪問內(nèi)部數(shù)據(jù)區(qū);PWORD、 PBYTE:訪問外部數(shù)據(jù)區(qū)當(dāng)前頁;XBYTE、 XWORD:訪問外部數(shù)據(jù)區(qū)。例:rval=CBYTE0 x0002; /指向程序存貯器的0002H地址 rval=XWORD 0 x0002; /指向外RAM的0004H地址 3. 緩沖區(qū)處理函數(shù)include包括搜索、比較、拷貝、移動等函數(shù) memchr; memcmp; memcpy; memmove;strcat; strchr ; strcmp; strcpy4. 字符轉(zhuǎn)換與字符分類includeisxdigit :判斷字符是否是16進(jìn)制數(shù)字字符 islower :是否是小寫isupper :

35、是否是大寫 tolower :字符轉(zhuǎn)換成小寫字符toupper :字符轉(zhuǎn)換成大寫字符5. 數(shù)學(xué)函數(shù)include包含常用的算術(shù)運(yùn)算函數(shù)sin :sin函數(shù) cos:cos函數(shù)abs:求絕對值 exp、log、sqrt、tan、pow:xy例3:如下圖,單片機(jī)P1口的P1.0和P1.1各接一個開關(guān)S1、S2,P1.4、P1.5、P1.6和P1.7各接一只發(fā)光二極管。由S1和S2的不同狀態(tài)來確定哪個發(fā)光二極管被點(diǎn)亮。#include “reg51.h”void main( ) while(1) /* 循環(huán)判斷S1、S2 */ char a;a=P1;a=a&0 x03;/*屏蔽高6位*/if (a

36、= =0) P1=0 x7F;else if (a= =1) P1=0 xBF;else if (a= =2) P1=0 xDF;else P1=0 xEF; 若要求用當(dāng)S1與S2同時按下時,4個LED全部點(diǎn)亮;當(dāng)僅有S1按下時,前2個LED點(diǎn)亮;當(dāng)僅有S2按下時,后2個LED點(diǎn)亮;無鍵按下時,4個LED全部熄滅。 #include /* 頭文件中包含了特殊功能寄存器P1和P2的定義*/ sbit S1 = P10; /* 定義位變量:將P1.0定義名稱為S1 */ sbit S2 = P11; void main() while(1) /* 循環(huán)判斷S1、S2 */ if(S1 = 0) &

37、 (S2 = 0) P1 = 0 x0F;else if(S1 = 0) P1 = 0 x3F;else if(S2 = 0) P1 = 0 xCF;else P1 = 0 xFF; /* 無鍵按下,熄滅所有LED */ 例4:如例1圖,用定時器0實(shí)現(xiàn)P1.7口所接LED燈每隔60ms 閃爍一次(設(shè)系統(tǒng)晶振頻率為12MHz)。 #include sbit P1_7 = P17; void main() P1 = 0 xff;/ *關(guān)閉P1口接的所有燈*/ TMOD = 0 x01; / *確定定時器工作模式*/ TH0 = 0 x15; TL0 = 0 xa0; TR0 = 1; / *啟動定

38、時器0工作*/ for( ; ; ) if(TF0) / *如果TF0等于1 */ TF0 = 0; / *清TF0 */ TH0 = 0 x15; / *重置初值*/ TL0 = 0 xa0; P1_7 = !P1_7; / *LED燈亮滅狀態(tài)切換*/ void time (void) interrupt 1 /* T0中斷服務(wù)程序入口,定時60ms */ TH0=(65536-60000)/256; / *重置初值*/ TL0 =(65536-60000) %256; P1_7 = !P1_7; / *LED燈亮滅狀態(tài)切換*/ void main(void) P1 = 0 xff;/ *關(guān)

39、閉P1口接的所有燈*/ TMOD=0 x01; /* T0為16位定時工作方式*/ TH0=(65536-60000)/256; /* 預(yù)置計數(shù)初值 */ TL0 =(65536-60000) %256; EA=1; /* CPU中斷開放 */ ET0=1; /* T0中斷開放 */ TR0=1; /* 啟動T0開始定時 */ while(1); /* 等待中斷 */ 例5:如下圖所示,編寫控制4位顯示器動態(tài)顯示的程序。位選碼輸出位選碼輸出段選碼輸出段選碼輸出#include “reg51.h”char code dispdata =0 x3F,0 x06,0 x5B,0 x4F,0 x66,

40、0 x6D,0 x7D, 0 x07,0 x7F,0 x6F; /*數(shù)字0-9對應(yīng)的段選碼*/char dis_data=2,4,6,8;void delay(void)/*延時1ms*/TH0=-500/256;TL0=-500%256;TR0=1;while(!TF0); /*TF0=0等待*/TF0=0;TR0=0;void disp(char i)/*顯示函數(shù)顯示函數(shù)*/static char ch=0 x01;P1=ch;P2= dispdatadis_datai;ch=ch1;if (ch= =0 x10) ch=0 x01;main( )char i;TMOD=0 x01;/*T

41、0為為16位定時工作方式位定時工作方式*/while(1)for(i=0; i4; i+) /*對對4位位LED掃描一遍掃描一遍*/disp(i);delay( );delay( ); delay( );例6 6 在下圖中接有五個共陰極數(shù)碼管的動態(tài)顯示接口電路,開關(guān)打向位置在下圖中接有五個共陰極數(shù)碼管的動態(tài)顯示接口電路,開關(guān)打向位置“1”1”時,顯示時,顯示“12345”12345”字樣,當(dāng)開關(guān)打向字樣,當(dāng)開關(guān)打向“2”2”時,顯示時,顯示“HELLO”“HELLO”字樣,試用字樣,試用C C5151編程實(shí)現(xiàn)功能。編程實(shí)現(xiàn)功能。 P1.1P1.789C51P1.0P1.2P1.4P1.3P1.

42、5P1.6P3.0P3.2P3.1P3.3P3.411111373GOEXTAL1XTAL2GNDVccEARST+5V+5VD6D0Q6Q0agg1230P210f#include#define uint unsigned int#define uchar unsigned charsbit P17=P17;main ( )uchar code tab15=0 x86,0 xdb,0 xcf,0 xe6,0 xed ;/ /* *“1-5”“1-5”的字形碼,因的字形碼,因P1.7P1.7接的開關(guān),最高位送的接的開關(guān),最高位送的“1”1”* */ / uchar code tab25=0 xf6,0 xf9,0 xb8,0 xb8,0 xbf;/ /* *“HELLO”“HELLO”的段碼的段碼 * */ /uchar i;while(1) delay( ) ; delay( ) ; P3=0 x01; for (i=0;i5 ; i+) if (P17=0) P1=tab1i; else P1=tab2i; P3=1; delay( ) ; 例7 7 記錄并顯示中斷次數(shù)。1 在主程序中判斷中斷次數(shù)在主程序中判斷

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論