第3章 KeilC語言及其程序設計_第1頁
第3章 KeilC語言及其程序設計_第2頁
第3章 KeilC語言及其程序設計_第3頁
第3章 KeilC語言及其程序設計_第4頁
第3章 KeilC語言及其程序設計_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第三章 單片機的C51語言 3.1.1 C51語言概述【P60】 C51是在標準C的基礎上,根據單片機存儲器硬件結構及內部資源,擴展了相應的數據類型和變量,而C51在語法規(guī)定、程序結構與設計方法上,都與標準C基本相同。Keil C語言的編譯器及編譯過程如圖3-1所示。圖3-1 Keil C語言的編譯器及編譯過程C語言是美國國家標準協會(ANSI)制定的編程語言標準,1987年ANSI公布87 ANSI C,即標準C語言。Keil C51語言是在ANSI C的基礎上針對51單片機的硬件特點進行的擴展,并向51單片機上移植,經過多年努力,C51語言已經成為公認的高效、簡潔而又貼近51單片機硬件的實

2、用高級編程語言。目前大多數的51單片機用戶都在使用C51語言來進行程序設計。用C51進行單片機軟件開發(fā),有如下優(yōu)點:(1)可讀性好。C51語言程序比匯編語言程序的可讀性好,因而編程效率高,程序便于修改?!綪53的匯編程序】(2)模塊化開發(fā)與資源共享。用C51開發(fā)出來的程序模塊可以不經修改,直接被其他項目所用,這使得開發(fā)者能夠很好地利用已有的大量的標準C程序資源與豐富的庫函數,減少重復勞動。(3)可移植性好。為某種型號單片機開發(fā)的C語言程序,只需將與硬件相關之處和編譯連接的參數進行適當修改,就可以方便地移植到其他型號的單片機上。例如,為51單片機編寫的程序通過改寫頭文件以及少量的程序行,就可以方

3、便地移植到PIC單片機上。(4)代碼效率高。當前較好的C51語言編譯系統(tǒng)編譯出來的代碼效率只比直接使用匯編語言低1020%左右,如果使用優(yōu)化編譯選項,效果會更好。3.1.2 C51的程序結構C51程序的基本單位是函數。一個C51源程序至少包含一個主函數,也可以是一個主函數和若干其他函數。主函數是程序的入口。下面通過一個可實現LED閃爍控制功能的源程序說明C51程序的基本結構。程序如下:【P60】#include / 51單片機頭文件void delay(); /延時函數聲明sbit p1_0=P10; /輸出端口定義main() /主函數While(1) /無限循環(huán)p1_0=0; /p1.0=

4、“0”,LED亮delay(); /延時p1_0=1; /p1.0=“1”,LED滅delay(); /延時void delay(void) /延時函數unsigned char i; /字符型變量i定義for (i=200;i0;i-); /循環(huán)延時 【在仿真時,可以不用連接電源,晶體振蕩器,復位電路】3.1.3 Keil C51的開發(fā)環(huán)境Keil C51是德國Keil Software公司開發(fā)的用于51系列單片機的C51語言開發(fā)軟件。Keil C51在兼容ANSI C的基礎上,又增加很多與51單片機硬件相關的編譯特性,使得開發(fā)51系列單片機程序更為方便和快捷,程序代碼運行速度快,所需存儲器

5、空間小,完全可以和匯編語言相媲美。它支持眾多的MCS-51架構的芯片,同時集編輯、編譯、仿真等功能于一體,具有強大的軟件調試功能,是眾多的單片機應用開發(fā)軟件中最優(yōu)秀的軟件之一。Keil C51已被完全集成到一個功能強大的全新集成開發(fā)環(huán)境(IDE)Vision3中【版本在不斷更新】,該環(huán)境集成了文件編輯處理、編譯鏈接、項目(Project)管理、窗口、工具引用和仿真軟件模擬器以及Monitor51硬件目標調試器等多種功能,這些功能可在Keil Vision3環(huán)境中進行操作。Vision3內部集成了源程序編輯器,并允許用戶在編輯源文件時就可設置程序調試斷點,便于在程序調試過程中快速檢查和修改程序。

6、此外,Vision3還支持軟件模擬仿真(Simulator)和用戶目標板調試(Monitor51)兩種工作方式。在軟件模擬仿真方式下不需任何51單片機及其外圍硬件即可完成用戶程序仿真調試。在用戶目標板調試方式下,利用硬件目標板中的監(jiān)控程序可以直接調試目標硬件系統(tǒng),使用戶節(jié)省購買硬件仿真器的費用。3.1.4 C51與標準C的主要區(qū)別不同的嵌入式處理器的C編譯系統(tǒng)與標準C的不同之處,主要是它們所針對的嵌入式處理器的硬件系統(tǒng)不同。Keil C51的基本語法與標準C相同,但對標準C進行了擴展。理解Keil C51對標準C的擴展部分是掌握Keil C51的關鍵。C51與標準C的主要區(qū)別如下:(1)頭文件

7、的差異。51系列單片機廠家有多個,它們的差異在于內部資源如定時器、中斷、I/O等數量以及功能的不同,而對使用者來說,只需要將相應的功能寄存器的頭文件加載在程序內,就可實現所具有的功能。因此,Keil C51系列的頭文件集中體現了各系列芯片的不同資源及功能。(2)數據類型的不同。51系列單片機包含位操作空間和位操作指令,因此Keil C51與ANSI C相比又擴展了4種類型,以便能夠靈活地進行操作。(3)數據存儲類型的不同。C語言最初是為通用計算機設計的,在通用計算機中只有一個程序和數據統(tǒng)一尋址的內存空間,而51系列單片機有片內、外程序存儲器,還有片內、外數據存儲器。標準C并沒有提供這部分存儲器

8、的地址范圍的定義。此外,對于80C51單片機中大量的特殊功能寄存器也沒有定義。(4)標準C語言沒有處理單片機中斷的定義。(5)Keil C51與標準C的庫函數有較大的不同。由于標準C的中的部分庫函數不適于嵌入式處理器系統(tǒng),因此被排除在Keil C51之外,如字符屏幕和圖形函數。有一些庫函數可以繼續(xù)使用,但這些庫函數都必須針對51單片機的硬件特點來作出相應的開發(fā),與標準C庫函數的構成與用法有很大的不同。例如庫函數printf和scanf,在標準C中,這兩個函數通常用于屏幕打印和接收字符,而在Keil C51中,它們主要用于串行口數據的收發(fā)。(6)程序結構的差異。由于51單片機的硬件資源有限,它的

9、編譯系統(tǒng)不允許太多的程序嵌套。其次,標準C所具備的遞歸特性不被Keil C51支持,在C51中,要使用遞歸特性,必須用reentrant進行聲明才能使用。但是從數據運算操作、程序控制語句以及函數的使用上來說,Keil C51與標準C幾乎沒有什么明顯的差別。如果程序設計者具備了有關標準C的編程基礎,只要注意Keil C51與標準C的不同之處,并熟悉AT89S51單片機的硬件結構,就能夠較快地掌握Keil C51的編程。3.2 C51語言程序設計基礎3.2.1 C51語言中的數據1. 數據類型【P63】Keil C51的基本數據類型如表3-1所示。針對80C51單片機的硬件特點,C51在標準C的基

10、礎上,擴展了4種數據類型(見表中最后4行)。注意:擴展的4種數據類型,不能使用指針對它們存取。表3-1 Keil C51支持的數據類型數據類型位數字節(jié)數值 域unsigned char810255signed char81-128+127unsigned int162065535signed int162-32768+32767unsigned long32404294967295signed long324-2147483648+2147483647float32410-3810E+38double64810-30810E+308bit10或1sbit10或1sfr810255sfr1616

11、2065536其中,有符號數據類型,可以忽略signed標識符,如signed int 等價于int,signed char 等價于char等。在C51語言程序中,有可能會出現在運算中數據類型不一致的情況。C51允許任何標準數據類型的隱式轉換。隱式轉換的優(yōu)先級順序如下:Bitcharintlongfloatsignedunsigned也就是說,當char型與int型進行運算時,先自動對char型擴展為int型,然后與int型進行運算,運算結果為int型。C51除了支持隱式類型轉換外,還可以通過強制類型轉換符“()”對數據類型進行人為的強制轉換。2. C51的擴展數據類型【P64】 80C51系

12、列單片機用特殊功能寄存器SFR來控制定時器、計數器、串口、并口和外圍設備。它們分別用位、字節(jié)和字進行訪問。與此對應,編譯器提供bit、sbit、sfr和sfr16數據類型訪問SFR。下面對表3-1中擴展的4種數據類型進行說明。(1) 位變量bit類型 利用它可以定義一個位變量或位函數,但不能定義位指針,也不能定義位數組。它的值可以是1(true), 也可以是0(false)。在C51中,允許用戶通過位類型符定義位變量。位類型符有兩個:bit和sbit??梢远x兩種位變量。bit位類型符用于定義一般的可位處理位變量。它的格式如下: bit 位變量名;例如:bit flag1;bit flag2;

13、所有的bit變量存放在80C51內部數據存儲區(qū)的(20H2FH)位段。因為這個區(qū)域只有16個字節(jié)長,所以在某個范圍內最多只能定義128個位變量。(2)特殊功能寄存器sfr類型特殊功能寄存器可以用sfr 來定義,通過名字或地址來引用特殊功能寄存器。51系列特殊功能寄存器在片內RAM區(qū)的80HFFH之間,“sfr” 數據類型占用一個內存單元。利用它可訪問80C51內部的所有特殊功能寄存器。 格式如下: sfr sfr_name=地址常數;sfr_name是特殊功能寄存器名,“地址常數”必須是一個常數,不允許用帶操作數的表達式。其數值范圍必須在特殊功能寄存器的地址范圍,即位于0x800xffH之間。

14、例如:sfr P0=0x80這一語句定義P0口在片內的寄存器,在后面語句中可用“P0=0xff”(使P0的所有引腳輸出為高電平)之類的語句來操作特殊功能寄存器。 同樣: sfr P1=0x90; sfr P2=0xa0;sfr P3=0xb0;P1、P2和P3是聲明的SFR名?!緦嶋H上,這些定義在REG51.H文件中已經定義過】(3)特殊功能寄存器sfr16類型“sfr16”數據類型占用兩個內存單元,用來定義16 位的特殊功能寄存器。sfr16和sfr一樣用于操作特殊功能寄存器。所不同的是它用于操作占兩個字節(jié)的特殊功能寄存器。特殊功能寄存器名一般用大寫字母表示。地址一般用直接地址形式(常數)。

15、不允許用帶操作數的表達式。而且必須是低位和高位字節(jié)中的低位字節(jié)的地址。例如DPTR。通過名字或地址來引用特殊功能寄存器。編譯器提供sfr16數據類型,將兩個8位的SFR作為一個16位的SFR來訪問。例如: sfr16 DPTR=0x82語句定義了片內16位數據指針寄存器DPTR,其低8位字節(jié)地址為82H,高8位字節(jié)地址為83H。在后面的語句中可以對DPTR進行操作。(4)特殊功能位 sbit在51系列單片機中,經常要訪問特殊功能寄存器中的某些位,可位尋址的特殊功能寄存器的位變量定義用關鍵字sbit。格式如下:sbit 位變量名=位地址;位地址可有2種形式:位直接地址,其取值范圍為0x800xf

16、f特殊功能寄存器名帶位號,特殊功能寄存器與位號之間一般用“”作間隔。【常用】例如:sbit EA=0xAF; 【IE寄存器的D7,即IE.7】【參見P27的表2.3】sbit EA=IE7; 【IE寄存器的D7,即IE.7】符號“”前面是特殊功能寄存器的名字,“”的后面數字定義特殊功能寄存器可尋址位在寄存器中的位置,取值必須是07。注意,不要把bit與sbit混淆。bit用來定義普通的位變量,值只能是二進制的0或1(位變量存放在RAM:20H2FH之間)。而sbit定義的是特殊功能寄存器的可尋址位,其值是可進行位尋址的特殊功能寄存器的位絕對地址(地址在80HFFH之間)?!纠?-5】sbit型

17、變量的定義。sbit P=0xd0;【 sbit P=PSW0; 】【見P27】sbit CY=0xd7;【 sbit P=PSW7; 】sfr P1=0x90;sbit P1_0=P10;sbit P1_1=P11;sbit P1_2=P12;sbit P1_3=P13;sbit P1_4=P14;sbit P1_5=P15;sbit P1_6=P16;sbit P1_7=P17;在C51中,為了用戶處理方便,C51編譯器把MCS-51單片機的常用的特殊功能寄存器和特殊位進行了定義,放在一個“reg51.h”或“reg52.h”的頭文件中,當用戶要使用時,只需要在使用之前用一條預處理命令#i

18、nclude 或#include 把這個頭文件包含到程序中,然后就可在程序中使用殊功能寄存器名和某些特殊位名稱。典型reg51.h頭文件的部分內容如下:C51編譯器在頭文件“reg51.h”中定義了全部sfr/sfr16和sbit變量。用一條預處理命令#include 把這個頭文件包含到C51程序中,無需重定義即可直接使用它們的名稱。REG51.H文件中定義的內容Header file for generic 80C51 and 80C31 microcontroller.-*/#ifndef _REG51_H_#define _REG51_H_/* BYTE Register */ 字節(jié)寄存

19、器【21個】sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0;sfr ACC = 0xE0;sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82;sfr DPH = 0x83;sfr PCON = 0x87;sfr TCON = 0x88;sfr TMOD = 0x89;sfr TL0 = 0x8A;sfr TL1 = 0x8B;sfr TH0 = 0x8C;sfr TH1 = 0x8D;sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98

20、;sfr SBUF = 0x99;/* BIT Register */ 可位尋址的位變量/* PSW */【程序狀態(tài)字】sbit CY = 0xD7;sbit AC = 0xD6;sbit F0 = 0xD5;sbit RS1 = 0xD4;sbit RS0 = 0xD3;sbit OV = 0xD2;sbit P = 0xD0;/* TCON */sbit TF1 = 0x8F;sbit TR1 = 0x8E;sbit TF0 = 0x8D;sbit TR0 = 0x8C;sbit IE1 = 0x8B;sbit IT1 = 0x8A;sbit IE0 = 0x89;sbit IT0 = 0

21、x88;/* IE */sbit EA = 0xAF;sbit ES = 0xAC;sbit ET1 = 0xAB;sbit EX1 = 0xAA;sbit ET0 = 0xA9;sbit EX0 = 0xA8;/* IP */ sbit PS = 0xBC;sbit PT1 = 0xBB;sbit PX1 = 0xBA;sbit PT0 = 0xB9;sbit PX0 = 0xB8;/* P3 */sbit RD = 0xB7;sbit WR = 0xB6;sbit T1 = 0xB5;sbit T0 = 0xB4;sbit INT1 = 0xB3;sbit INT0 = 0xB2;sbit

22、 TXD = 0xB1;sbit RXD = 0xB0;/* SCON */sbit SM0 = 0x9F;sbit SM1 = 0x9E;sbit SM2 = 0x9D;sbit REN = 0x9C;sbit TB8 = 0x9B;sbit RB8 = 0x9A;sbit TI = 0x99;sbit RI = 0x98;#endif3. 數據的存儲類型【P65】 針對80C51存儲空間的特點,可以利用存儲空間的修飾符,來指明所定義的變量應分配在什么樣的存儲空間。C51存儲類型與80C51的實際存儲空間的對應關系見表3-2。下面對表3-2作以說明。(1)片內數據存儲器 片內數據存儲區(qū)是可讀

23、/寫的。80C51系列最多可有256字節(jié)的內部數據存儲區(qū)。內部數據區(qū),可以分成3個不同的存儲類型data、idata和bdata。data:片內直接尋址區(qū),位于片內RAM的低128字節(jié)。為片內直接尋址的RAM空間,尋址范圍為0127(00H7FH,主要在30H7FH之間)。在此空間內,存取速度最快。idata:片內間接尋址區(qū),片內RAM所有地址單元(00HFFH)。為片內間接尋址的RAM空間,尋址范圍0255。由于只能間接尋址,訪問速度比直接尋址慢。【只有52系列才有】bdata:片內位尋址區(qū),位于片內RAM位尋址區(qū)20H2FH,位地址范圍位0127。在此空間允許按字節(jié)和按位尋址混合訪問?!救?/p>

24、果不用位變量,仍然可以作為字節(jié)地址訪問】bit定義的變量,嚴格來說只能是bdata。例如:unsigned char bdata flag; 表3-2 存儲器類型說 明data直接訪問的內部數據存儲器,訪問速度最快(位于片內RAM的低128字節(jié),字節(jié)地址:00H7FH)bdata可位尋址的內部數據存儲器,可用字節(jié)方式,也可用位方式訪問,位于20H2FH(16個字節(jié))idata間接訪問的內部數據存儲器,可以訪問所有的內部存儲空間(256字節(jié))【只有52系列才有】pdata片外RAM的一個分頁尋址區(qū),每頁256字節(jié)xdata外部數據存儲器RAM(64KB),常用于存放不常用的變量或等待處理的數據,

25、字節(jié)地址:0000HFFFFHcode外部程序存儲器空間(64KB),常用于存放數據表格、常數等固定信息(2)片外數據存儲器 外部數據存儲區(qū)是可讀/寫的??赏ㄟ^一個數據指針加載一個地址來間接訪問外部數據區(qū)。因此,訪問外部數據區(qū)比訪問內部數據存儲區(qū)慢。 外部數據存儲區(qū)最多可有64KB。由于硬件設計時,要把外圍設備映射到該存儲區(qū),所以這些地址不一定都能用來作為數據存儲區(qū)。 編譯器提供兩種不同的存儲類型來訪問外部數據xdata和pdata。 xdata該標識是指外部數據存儲區(qū)(64KB)內的任何地址,尋址范圍為065535【字節(jié)地址:0000HFFFFH】。pdata該標識符僅指一頁或256字節(jié)的外

26、部數據存儲區(qū),尋址范圍為0255。 在定義變量時,通過指明存儲器類型,可以將所定義的變量存儲在指定的存儲區(qū)域中。 訪問內部數據存儲器比訪問外部數據存儲器快得多。因此,應該把頻繁使用的變量放置在內部數據存儲器中,把很少使用的變量放在外部數據存儲器中。 在變量聲明中,可以包括存儲器類型和singed或unsinged屬性。例如: unsigned char data var1; unsigned char code text=”Enter Parameter”; unsigned long xdata array100; unsigned char xdata vector1044; unsign

27、ed char bdata flag; 【如果位變量區(qū)有未用的單元,可以進行字節(jié)訪問】unsigned char code data=0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,;/把常數放到程序存儲器中如果在變量的定義中,沒有包括存儲器類型,那么將自動選用默認的存儲器類型。(3)片外程序存儲器code:外部程序存儲器的64KB空間。程序存儲區(qū)用來存放程序代碼、數據及表格(數據及表格中的數據是不變的)。程序的代碼(CODE)存儲區(qū)是只讀的,不能寫入。硬

28、件決定最多可能有64KB的程序存儲區(qū)?!疽驗槭?6位】用code標識符來訪問片內、片外統(tǒng)一編址的程序存儲區(qū),尋址范圍為065535。【P66】如果在定義變量時,省略了存儲類型說明,C51編譯器會根據當前編譯模式自動認定默認的存儲類型。編譯模式分為:小編譯模式(SMALL)、緊湊編譯模式(COMPACT)和大編譯模式(LARGE)3種,具體的內容見下表:【在keil中要進行選擇,目前只用SMALL就可以了】3種編譯模式的特點小結編譯模式變量存儲區(qū)域默認存儲類型特點SMALL片內低128RAMdata訪問數據的速度最快,但由于存儲容量較小,難于滿足需要定義較多變量的場合COMPACT片外頁256B

29、RAMpdata介于兩者之間,且受片外RAM的容量限制LARGE片外64KBRAMxdata訪問數據的效率不高,但由于存儲容量大,可滿足需要定義較多變量的場合所以,在SMALL編譯模式下,語句char a 等價于char data a;而在LARGE編譯模式下,語句char a等價于char xdata a。一般采用SMALL模式,所以,在變量聲明中,如果沒有修飾符,則數據默認的存儲空間為data型,也就是在片內RAM中。對單片機編程,正確地定義數據類型以及存儲類型,是所有編程者在編程前都需要首先考慮的問題。在資源有限的條件下,如何節(jié)省存儲單元并保證運行效率,是對開發(fā)者的一個考驗。只有對C51

30、中的各種數據類型以及存儲類型非常熟練的掌握,才能運用自如。定義變量類型應考慮如下問題:程序運行時該變量可能的取值范圍,是否有負值,絕對值有多大,以及相應需要的存儲空間大小。在夠用的情況下,盡量選擇8位即一個字節(jié)的char型,特別是unsiged char。對于51系列這樣的定點機而言,浮點類型變量將明顯增加運算時間和程序長度,如果可以的話,盡量使用靈活巧妙的算法來避免浮點變量的引入。定義數據的存儲類型通常遵循如下原則:只要條件滿足,盡量選擇內部直接尋址的存儲類型data,然后選擇idata即內部間接尋址。對于那些經常使用的變量要使用內部尋址。在內部數據存儲器數量有限或不能滿足要求的情況下才使用

31、外部數據存儲器。選擇外部數據存儲器可先選擇pdata類型,最后選用xdata類型。需指出,擴展片外存儲器,原理上雖很簡單,但在實際開發(fā)中,很多時候,會帶來不必要的麻煩,如可能降低系統(tǒng)穩(wěn)定性、增加成本、拉長開發(fā)和調試周期等,推薦充分利用片內存儲空間。另外,通常的單片機應用都是面對小型的控制,代碼比較短,對于程序存儲區(qū)的大小要求很低,常常是片內RAM很緊張而片內Flash ROM很富裕,因此如果實時性要求不高,可考慮將一些子函數的常量數據做成數據表,放置在程序存儲區(qū),當程序運行時,進入子函數動態(tài)調用下載至RAM即可,退出子函數后立即釋放該內存空間。3.2.3 一個簡單的C51程序一個C51源程序是

32、由一個個模塊化的函數所構成,函數是指程序中的一個模塊,main()函數為程序的主函數,其他若干個函數可以理解為一些子程序。一個C51源程序無論包含了多少函數,它總是從main()函數開始執(zhí)行,不論main()函數位于程序的什么位置。程序設計者就是編寫一系列的函數模塊,并在需要的時候調用這個函數,實現程序所要求的功能。1. C51程序與函數下面通過一個簡單C51程序,認識C51程序與函數。【例3-1】 在80C51的P1.0腳接有一只發(fā)光二極管,二極管的陰極接P1.0腳,陽極通過限流電阻接+5V,現在讓發(fā)光二極管每隔800ms閃滅,占空比為50%。已知單片機時鐘晶振為12MHz,即每個機器周期1

33、s,采用軟件延時的方法,參考程序如下:#include / 包含reg51.h 頭文件sbit P10=P10; / 定義位變量P1.0 ,也可使用sbit P10=0x90void delay(unsigned int count) / 延時函數Delay( ),count是形式參數 / 兩個花括號之間為函數Delay( )的函數體unsigned int i,j; / 定義變量i,jfor(i=0; icount;i+) / 如果icount,則i加1 /在時鐘頻率為12MHz時,循環(huán)120次,大約為1ms for(j=0;j120;j+) / 如果j大于=大于或等于=小于或等于=等于!=

34、不等于4. 位運算C51中的位運算符及其說明如表3-6所示。表3-6 位運算其說明符號說 明&按位與按位或按位異或按位取反右移【例】設a=0x54=01010100B,b=0x3b=00111011B,則a&b、a|b、ab、a、a2分別為多少?a=0x54=01010100Bb=0x3b=00111011B a&b=00010000b=0x10 a|b=01111111B=0x7f ab=01101111B=0x6f a=10101011B=0xab a2=01010000B=0x50 【a2=00001110B=0x0e 【b=2】5 復合賦值運算符C51語言中支持在賦值運算符“=”的前面

35、加上其它運算符,組成復合賦值運算符。下面是C51中支持的復合賦值運算符:+= 加法賦值 -+ 減法賦值*= 乘法賦值 /= 除法賦值%= 取模賦值 &= 邏輯與賦值 |= 邏輯或賦值 = 邏輯異或賦值= 邏輯非賦值 = 右移位賦值 =2相當于x=x2。3.2.5 C51的分支與循環(huán)程序結構程序結構上可把程序分為三類,即順序、分支和循環(huán)結構。順序結構是程序的基本結構,程序自上而下,從main()的函數開始一直到程序運行結束,程序只有一條路可走,沒有其他的路徑可以選擇。順序結構比較簡單和便于理解,這里介紹分支結構和循環(huán)結構。1. 分支結構程序(1) 只有兩條分支的時候用If (條件) 分支1els

36、e 分支2(2) 分支較多時在分支較多時的情況下使用switch語句。switch ( ) case( ):語句; break; case( ):語句;break;default:語句;break;注意:每個switch分支必須有一個break語句,否則程序并不能跳出switch,就會繼續(xù)執(zhí)行case后面的case語句。2. 循環(huán)結構程序循環(huán)語句有以下三種。(1)for循環(huán)格式為:for(循環(huán)體初始化;循環(huán)體執(zhí)行條件;循環(huán)體執(zhí)行后操作) 循環(huán)體 花括號中為循環(huán)體內容。(2)while循環(huán)格式為:while(循環(huán)體執(zhí)行條件) 花括號中為循環(huán)體內容。 (3)do while循環(huán)格式為:do 花括號

37、 中為循環(huán)體內容while(循環(huán)體執(zhí)行條件)前兩種循環(huán)是先判斷循環(huán)條件是否滿足,才決定循環(huán)體是否執(zhí)行;而“do while循環(huán)”是在執(zhí)行完循環(huán)體后再判斷條件是否滿足,再決定循環(huán)體是否繼續(xù)執(zhí)行。三種循環(huán)中,經常使用的是for語句和while語句。下面來說明for語句的應用。關于循環(huán),需說明的是,在無操作系統(tǒng)的控制器和處理器上運行的程序,主體通常采用輪詢方式,即把所有的操作包含在一個while(1)中,如例3-1。這樣的無限循環(huán)在面向通用計算機的軟件設計中是不被允許的,然而嵌入式系統(tǒng)軟件設計中,則由于其硬件構成和使用需求,常常采用這種無限循環(huán)。3.2.6 絕對地址訪問使用C51運行庫中預定義宏C5

38、1編譯器提供了一組宏定義來對51系列單片機的code、data、pdata和xdata空間進行絕對尋址。規(guī)定只能以無符號數方式訪問,定義了8個宏定義,其函數原型如下:#define CBYTE (unsigned char volatile code *) 0)#define DBYTE (unsigned char volatile data *) 0)#define PBYTE (unsigned char volatile pdata *) 0)#define XBYTE (unsigned char volatile xdata *) 0)#define CWORD (unsigned

39、 int volatile code *) 0)#define DWORD (unsigned int volatile data *) 0)#define PWORD (unsigned int volatile pdata *) 0)#define XWORD (unsigned int volatile xdata *) 0)這些函數原型放在absacc.h文件中。使用時須用預處理命令把該頭文件包含到文件中,形式為:#include 。其中:CBYTE以字節(jié)形式對code區(qū)尋址,DBYTE以字節(jié)形式對data區(qū)尋址,PBYTE以字節(jié)形式對pdata區(qū)尋址,XBYTE以字節(jié)形式對xdata

40、區(qū)尋址,CWORD以字形式對code區(qū)尋址,DWORD以字形式對data區(qū)尋址,PWORD以字形式對pdata區(qū)尋址,XWORD以字形式對xdata區(qū)尋址。訪問形式如下: 宏名地址 宏名為CBYTE、DBYTE、PBYTE、XBYTE、CWORD、DWORD、PWORD或XWORD。地址為存儲單元的絕對地址,一般用十六進制形式表示?!纠?-7】絕對地址對存儲單元的訪問。#include /將絕對地址頭文件包含在文件中#include /將寄存器頭文件包含在文件中#define uchar unsigned char /定義符號uchar為數據類型符unsigned char#define ui

41、nt unsigned int /定義符號uint為數據類型符unsigned intvoid main(void)uchar var1;uint var2;var1=XBYTE0x0005; /XBYTE0x0005訪問片外RAM的0005字節(jié)單元var2=XWORD0x0002; /XWORD0x0002訪問片外RAM的0002字單元xval=XBYTE0x0002; /把外部存儲區(qū)地址0x0002的數據存入變量xval中XWORD0x0002=0x2000; /把0x2000送到外部存儲區(qū)地址為0x0002的單元#define DAC0832 XBYTE0x7fff /定義DAC0832

42、的端口地址DAC0832=0x80; /啟動一次D/A轉換.while(1);在上面程序中,其中XBYTE0x0005就是以絕對地址方式訪問的片外RAM 0005字節(jié)單元;XWORD0x0002就是以絕對地址方式訪問的片外RAM 0002字單元。3.2.7 使用C51擴展關鍵字“_at_” 使用_at_對指定的存儲器空間的絕對地址進行訪問,一般格式如下: 存儲器類型 數據類型說明符 變量名 _at_ 地址常數; 其中,存儲器類型為data、bdata、idata、pdata等C51能識別的數據類型,如省略則按存儲模式規(guī)定的默認存儲器類型確定變量的存儲器區(qū)域;數據類型為C51支持的數據類型。地址

43、常數用于指定變量的絕對地址,必須位于有效的存儲器空間之內;使用“_at_”定義的變量必須為全局變量?!纠客ㄟ^_at_實現絕對地址的訪問。#define uchar unsigned char/定義符號uchar為數據類型符unsigned char#define uint unsigned int /定義符號uint為數據類型符unsigned intvoid main(void)data uchar x1 _at_ 0x40; /在data區(qū)中定義字節(jié)變量x1,它的地址為40Hxdata uint x2 _at_ 0x2000; /在xdata區(qū)中定義字變量x2,它的地址為2000Hx1=

44、0xff;x2=0x1234;.while(1);3.2.7 C51中斷服務函數的定義 由于標準C沒有處理單片機中斷的定義,為直接編寫中斷服務程序,C51編譯器對函數的定義進行了擴展,增加了一個擴展關鍵字interrupt,使用該關鍵字可以將一個函數定義成中斷服務程序。由于C51編譯器在編譯時對聲明為中斷服務程序的函數自動添加了相應的現場保護、阻斷其他中斷、返回時恢復現場等處理的程序段,因而在編寫中斷服務函數時可不必考慮這些問題,減輕了用匯編語言編寫中斷服務程序的繁瑣程度,而把精力放在如何處理引發(fā)中斷請求的事件上。中斷服務函數的一般形式為:void 函數名(void)interrupt n using m在函數聲明時,用“interrupt n”語句,可以把所聲明的函數定義為一個中斷服務程序。從定義中可以看出,中斷函數必須是無參數、無返回值的函數。關鍵字interrupt后面的 n是中斷號,對于AT89S51,取值為04,編譯器從8n+3處產生中斷向量。AT89S51中斷源對應的中斷號和中斷向量見表3-3。表3-3 中斷號n和中斷向量中斷號n中斷源中斷向量(8n+3)0外部中斷00003H1定時器0中斷000BH2外部中斷10013H3定時器1中斷001BH4串行口中斷0023H其他值(531)預留(8n+3)80C51在

溫馨提示

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

最新文檔

評論

0/150

提交評論