計算機控制技術西電版PPT第2章單片機C語言編程_第1頁
計算機控制技術西電版PPT第2章單片機C語言編程_第2頁
計算機控制技術西電版PPT第2章單片機C語言編程_第3頁
計算機控制技術西電版PPT第2章單片機C語言編程_第4頁
計算機控制技術西電版PPT第2章單片機C語言編程_第5頁
已閱讀5頁,還剩51頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

17、指向的存貯區以多少個單元作一個數據單位,當程序通過指針對該區操作時,將按此規定的單元個數的內容作為一個數據操作。 4) 指針變量自身的存貯類型,即指針處于什么區與自身的長度無關,該聲明可位于聲明語句的開頭,也可在“*”和變量名之間。此項由編譯模式放在默認區,如無規定編譯模式,通常在data區。1. 特殊功能寄存器SFR定義 C51提供了一種自主形式的定義方式,使用特定關鍵字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 (增強型為reg52.h),在該文件中對所有的特殊功能寄存器的進行了sfr定義, 對特殊功能寄存器的有位名稱的可尋址位進行了sbit定義,因此,只要用包含語句#include,就可以直接引用特殊功能寄存器名,或直接引用位名稱。要特別注意:在引用時特殊功能寄存器或者位名稱必須大寫。 sfr和sbit只能在函數外使用,一般放在程序的開頭。 2.對位變量的定義 C51對位變量的定義有三種方法: 將變量用bit類型的定義符定義為bit類型: 如 bit mn; mn為位變量,

19、其值只能是“0”或“1”,其位地址由C51任意分配。 采用字節尋址變量.位的方法: 如 int bdata ibase; /*ibase定義為整型變量*/ sbit mybit=ibase15;/*mybit定義為ibase的D15位*/ 這里位是運算符“”相當于匯編中的“.”,其后的最大取值依賴于該位所在的字節尋址變量的定義類型,如定義為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:字節地址位表示 例如 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可對不同的存貯區進行訪問。該頭文件的函數有: CBYTE (訪問code區字符型) DBYTE (訪

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

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

23、_at_ 0 x40; /在data區定義字節變量x1,它的地址為40H xdata unsigned int x2_at_ 0 x2000; /在xdata區定義字變量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;/定義花樣數據,數據存放在片內CO

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

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

26、2. a=0 xea; 表達式a2值為A8H,即a值左移兩位,移位后空白 位補0。 6. 自增、自減運算符: +i,-i (在使用i之前,先使i值加1,減1) i+,i- (在使用i之后,再使i值加1,減1) 例: 設i原值為5 j=+i 則j值為6,i值也為6 j=i+ 則j值為5,i值為6 ! (非)算術運算關系運算&和|= (賦值運算)例2:P1.0接一開關, P1.1接一發光二極管。開關打開時,二極管不亮,開關閉合時,二極管亮。 #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程序由函數組成。 從用戶使用角度劃分,函數分為庫函數和用戶自定義函數 庫函數是編譯系統為用戶設計的一系列標準函數,用戶只需調用,而無需自己去編寫這些復雜的函數,如前面所用到的頭文件reg51.h等,有的頭文件中包括一系列函數,要使用其中的函數必須先使用#include包含語句,然后才能調用。 用戶自定義函數是用戶根據任務編寫的函數。 從參數形式上函數分為無參函數和有參函數。 有參函數即是在調用時,調用函數用實際參數代替形式參數,調用完返回結果給調用函數。 C51中函數的定義格式與標準C相似,增加了以下內

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

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

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

31、表達式的運算對象,如 result=2result=2* *get(a,b);get(a,b); 此時getget函數中的a,ba,b應為實參,其以返回值參與式中的運算。 被調函數作為另一個函數的實際參數 如 m=max(a,get(a,b)m=max(a,get(a,b);函數get(a,b)get(a,b)作為函數max()max()的一個實際參數。 注:1)1)如果被調函數出現在主調函數之后,在主調函數前應對被調函數進行說明,形式為: 返回值類型 被調函數名( (形式參數表) ); 2)2)如果被調函數出現在主調函數之前,可以不對被調函數說明。下面以一個簡單例子來說明: 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); 上例被調函數在主調函數前,不用說明。 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); 上例中被調函數在主調函數后,在前面對被調函數進行說明。庫函數 是編譯系統為用戶設計的一系列標準函數,用戶只需調用,而無需自己去編寫這些復雜的函數,如前面所用到的頭文件reg51.h、absacc.h等,有的

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

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

35、是否是大寫 tolower :字符轉換成小寫字符toupper :字符轉換成大寫字符5. 數學函數include包含常用的算術運算函數sin :sin函數 cos:cos函數abs:求絕對值 exp、log、sqrt、tan、pow:xy例3:如下圖,單片機P1口的P1.0和P1.1各接一個開關S1、S2,P1.4、P1.5、P1.6和P1.7各接一只發光二極管。由S1和S2的不同狀態來確定哪個發光二極管被點亮。#include “reg51.h”void main( ) while(1) /* 循環判斷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; 若要求用當S1與S2同時按下時,4個LED全部點亮;當僅有S1按下時,前2個LED點亮;當僅有S2按下時,后2個LED點亮;無鍵按下時,4個LED全部熄滅。 #include /* 頭文件中包含了特殊功能寄存器P1和P2的定義*/ sbit S1 = P10; /* 定義位變量:將P1.0定義名稱為S1 */ sbit S2 = P11; void main() while(1) /* 循環判斷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實現P1.7口所接LED燈每隔60ms 閃爍一次(設系統晶振頻率為12MHz)。 #include sbit P1_7 = P17; void main() P1 = 0 xff;/ *關閉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燈亮滅狀態切換*/ void time (void) interrupt 1 /* T0中斷服務程序入口,定時60ms */ TH0=(65536-60000)/256; / *重置初值*/ TL0 =(65536-60000) %256; P1_7 = !P1_7; / *LED燈亮滅狀態切換*/ void main(void) P1 = 0 xff;/ *關

39、閉P1口接的所有燈*/ TMOD=0 x01; /* T0為16位定時工作方式*/ TH0=(65536-60000)/256; /* 預置計數初值 */ TL0 =(65536-60000) %256; EA=1; /* CPU中斷開放 */ ET0=1; /* T0中斷開放 */ TR0=1; /* 啟動T0開始定時 */ while(1); /* 等待中斷 */ 例5:如下圖所示,編寫控制4位顯示器動態顯示的程序。位選碼輸出位選碼輸出段選碼輸出段選碼輸出#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; /*數字0-9對應的段選碼*/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)/*顯示函數顯示函數*/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 在下圖中接有五個共陰極數碼管的動態顯示接口電路,開關打向位置在下圖中接有五個共陰極數碼管的動態顯示接口電路,開關打向位置“1”1”時,顯示時,顯示“12345”12345”字樣,當開關打向字樣,當開關打向“2”2”時,顯示時,顯示“HELLO”“HELLO”字樣,試用字樣,試用C C5151編程實現功能。編程實現功能。 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接的開關,最高位送的接的開關,最高位送的“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 記錄并顯示中斷次數。1 在主程序中判斷中斷次數在主程序中判斷

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論