第五章單片機的C語言程序設計及仿真調(diào)試_第1頁
第五章單片機的C語言程序設計及仿真調(diào)試_第2頁
第五章單片機的C語言程序設計及仿真調(diào)試_第3頁
第五章單片機的C語言程序設計及仿真調(diào)試_第4頁
已閱讀5頁,還剩84頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第五章單片機的C語言程序設計及仿真調(diào)試disable任課教師:劉忠國山東大學課程中心網(wǎng)站:

http:///G2S/stcmcu.cc宏晶官方網(wǎng)站:http://STC單片機編譯(匯編)/編程(燒錄)/仿真工具說明書;stc15系列單片機器件手冊等keilμvision軟件下載及指導手冊(Help→μvisionHelp)/KeilSoftware–Cx51編譯器用戶手冊:Cx51編譯器--對傳統(tǒng)和擴展的8051微處理器的優(yōu)化的C編譯器和庫參考2第五章單片機的C語言程序設計及仿真調(diào)試本章學習目標掌握單片機C語言程序中的常用功能掌握KeilC的程序設計掌握IAP15W4K58S4單片機C語言程序調(diào)試過程3第五章單片機的C語言程序設計及仿真調(diào)試§5.1C51程序的基本語法5.1.1關鍵字5.1.2C51程序的一般結構5.1.3數(shù)據(jù)類型5.1.4運算符和表達式§5.2KeilC51程序的語句5.2.1表達式語句5.2.2條件語句5.2.3開關語句5.2.4循環(huán)語句5.2.5goto、break、continue和return語句§5.3函數(shù)5.3.1函數(shù)的定義與調(diào)用5.3.2KeilC51函數(shù)§5.4KeilC51庫函數(shù)§5.5預處理命令§5.6單片機C語言程序框架4匯編語言和C語言的選擇問題設計規(guī)模較小的嵌入式應用系統(tǒng)時,可以使用匯編語言。因為代碼一般不長,且較簡單。當程序比較復雜,且沒有很好的注釋時,使用匯編語言編寫的程序,可讀性和可維護性會很差,代碼的可重用性也比較低。使用C語言編程,編寫簡單、直觀易讀、便于維護、通用性好。在控制任務比較復雜或者具有大量運算的系統(tǒng)中,C語言優(yōu)勢明顯。由于模塊化,用C語言編寫的程序具有很好的可移植性。5§5.1C51程序的基本語法1.標準C語言(ANSIC)的關鍵字(1)數(shù)據(jù)類型關鍵字1)基本數(shù)據(jù)類型void、char、int、float、double2)類型修飾關鍵字short、long、signed、unsigned3)復雜類型關鍵字struct、union、enum、typedef、sizeof4)存儲級別關鍵字auto、static、register、extern、const、volatile§5.1.1關鍵字6§5.1.1關鍵字(2)流程控制關鍵字1)跳轉結構return、continue、break、goto2)分支結構if、else、switch、

case、default3)循環(huán)結構for、do、

while2.KeilC51編譯器支持的關鍵字bit、sbit、sfr、sfr16、data、bdata、idata、pdata、

xdata、

code、

interrupt、

reentrant、using7預處理命令

//以#開頭的命令,用于包含頭文件、定義常數(shù)等全局變量聲明

//全局變量雖然方便傳遞參數(shù),但不宜多函數(shù)1的聲明......函數(shù)n的聲明voidmain(void) //主函數(shù){

局部變量聲明

//局部變量只能在所定義的函數(shù)內(nèi)部引用

可執(zhí)行語句

函數(shù)調(diào)用

無限循環(huán)}§5.1.2C51程序的一般結構8//一般函數(shù)的定義函數(shù)1(形式參數(shù)聲明){

局部變量聲明

可執(zhí)行語句}......函數(shù)n(形式參數(shù)聲明){

局部變量聲明

可執(zhí)行語句}§5.1.2C51程序的一般結構9//中斷函數(shù)的實現(xiàn)voidISRname(void)interruptn//n為中斷號{

局部變量聲明

可執(zhí)行語句}注意如下幾點:(1)所有函數(shù)以花括號“{”開始,以花括號“}”結束,包含在“{}”內(nèi)的部分稱為函數(shù)體?;ɡㄌ柋仨毘蓪Τ霈F(xiàn),如果一個函數(shù)內(nèi)有多對花括號,則最外層的花括號為函數(shù)體的范圍。為了增加程序的可讀性,應采用縮進方式書寫?!?.1.2C51程序的一般結構10注意如下幾點:(2)建議一行寫一條語句,每條語句最后必須以一個分號“;”結尾。(3)每個變量必須先定義后引用。在函數(shù)內(nèi)部定義的變量為局部變量,又稱為內(nèi)部變量,只有定義它的那個函數(shù)才能使用。在函數(shù)外部定義的變量為全局變量,又稱為外部變量,在定義它的那個程序文件中的函數(shù)都可以使用。(4)程序語句的注釋放在雙斜杠“//”之后,或者放在“/*......*/”之內(nèi)?!?.1.2C51程序的一般結構111.常量和變量常量包括整形常量、浮點型常量、字符型常量(如‘a(chǎn)’:單引號字符

)

及字符串常量(雙引號單個或多個字符,如"a","Happy")等。變量是一種在程序執(zhí)行過程中其值不斷變化的量。使用一個變量之前,必須先進行定義。§5.1.3數(shù)據(jù)類型

1.常量和變量2.數(shù)據(jù)類型(1)基本數(shù)據(jù)類型基本數(shù)據(jù)類型是不可以再分解為其他類型的數(shù)據(jù)類型。如char(字符型)、int(整型)、long(長整型)、float(浮點型)等。122.數(shù)據(jù)類型(2)構造數(shù)據(jù)類型構造數(shù)據(jù)類型是根據(jù)已定義的一個或多個數(shù)據(jù)類型用構造的方法來定義的?!?.1.3

數(shù)據(jù)類型

2.數(shù)據(jù)類型在C語言中,構造類型有以下幾種:數(shù)組類型結構類型聯(lián)合類型13(3)指針類型指針是一種特殊的,具有重要作用的數(shù)據(jù)類型。用來表示某個量在內(nèi)存中的地址。§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型(4)空類型函數(shù)調(diào)用后并不需要向調(diào)用者返回函數(shù)值,這種函數(shù)可以定義為“空類型”。其類型說明符為void。14C51編譯器除了支持上述數(shù)據(jù)類型外,還支持以下幾種擴充數(shù)據(jù)類型:(1)bit:位類型。bit型變量的位地址由編譯器分配。(2)sfr:特殊功能寄存器,用來控制中斷、定時器、計數(shù)器、串口、I/O及其他部件。(3)sfr16:16位特殊功能寄存器。(4)sbit:位尋址?!?.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型bit與sbit的用法區(qū)別:定義的bit型變量的位地址在00H~7FH之間,具體地址值不定,由編譯器隨機分配。sbit位尋址:該數(shù)據(jù)類型用一個指定的變量作為基地址然后用其位的位置來得到一個實際的位地址。15(1)bit:位類型??梢远x一個位變量,但不能定義位指針,也不能定義位數(shù)組。

C51程序中,函數(shù)參數(shù)和返回值也可以是位變量。例:bit

finish_flag=0;bittestfunc(bitvar1,bitvar2){

...

return(0);};§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型所有bit型變量的都被定位在8051片內(nèi)RAM的可位尋址區(qū)20H~2FH,共16個字節(jié),所以最多只能聲明128個bit型位變量。16(2)sfr:字節(jié)尋址。語法如下:

sfrsfr_name=int_constant;如

sfrP0=0x80;

0x80為P0口的地址,“=”后為常數(shù),且這個常數(shù)必須在特殊功能寄存器的地址范圍內(nèi),即0x80到0xFF之間?!?.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型(3)sfr16:字尋址如sfr16DPTR=0x82;

指定DPTR的地址DPL=0x82,DPH=0x83。(4)sbit:位尋址。用于定義可位尋址變量。可定義8051片內(nèi)RAM的可尋址位,或特殊功能寄存器的可尋址位。17§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型(4)

sbit:位尋址。定義可位尋址變量。定義片內(nèi)RAM的可尋址位,

或特殊功能寄存器的可尋址位。C51編譯器提供了存儲類型bdata,bdata存儲類型變量位于片內(nèi)RAM的可位尋址區(qū),可字節(jié)尋址,或位尋址,因此bdata型變量可用sbit指定其中任意位為可位尋址變量。需注意:使用bdata和sbit定義的變量必須是全局變量,并且用sbit定義為位尋址變量時要求基址對象的存儲器類型必須為bdata

(特殊功能寄存器除外)。sbit聲明方法:

sbitbitname=bdata型變量或sfr_name^bit_number;其中,sfr_name

是已定義SFR的名字,bit_number是位號,其數(shù)值取決于基址對象的數(shù)據(jù)類型,對char和SFR而言是(0~7)

,對int型而言是(0~15),對long型而言是(0~31)。18§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型sbit聲明方法:

sbitbitname=bdata型變量或sfr_name^bit_number;其中,sfr_name

是已定義SFR的名字,bit_number是位號,其數(shù)值取決于基址對象的數(shù)據(jù)類型,對char和SFR而言是(0~7),對int型而言是(0~15),對long型而言是(0~31)。如:unsignedcharbdataflag;//flag為bdata型無符號字符變量int

bdata

ibase

;//定義ibase為bdata整型變量使用sbit可位尋址變量如下:

sbitflag0=flag^0

;//定義flag0為flag的第0位

sbitmybit15=ibase^15;//mybit15為ibase的第15位

sbitCY=PSW^7;//定義CY為PSW的第7位sbitP00=P0^0;//定義P0.0口線的名稱是P0019sbit可以有下面聲明方法:方法1:sbitbitname=sfr_name^bit_number;其中,sfr_name必須是已定義的SFR的名字,bit_number是位號(0~7)。如:sbitCY=PSW^7;//定義CY為PSW的第7位。方法2:sbitbitname=sfr_address^bit_number;

其中,sfr_address是SFR所在的地址(0x80~0xff),bit_number是位號(0~7)。如:sbitOV=0xD0^2;//定義PSW中的OV位方法3:sbitbitname=bit_address;其中,bit_address是位地址。如:sbitEA=0xAF;//第0xAF位為EA§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型20KeilC51編譯器支持的數(shù)據(jù)類型如表5-1所示。數(shù)據(jù)類型位數(shù)(bit)字節(jié)數(shù)(byte)取值范圍bit11/80或1signedchar81-128~+127unsignedchar810~255enum8/161or2-128~+127or-32768~+32767signedshort162-32768~+32767unsignedshort1620~65535signedint162-32768~+32767unsignedint1620~65535signedlong324-2147483648~+2147483647unsignedlong3240~4294967295float324+1.175494E38~+3.402823E+38sbit11/80或1sfr810~255sfr161620~65535表5-1KeilC51編譯器支持的數(shù)據(jù)類型§5.1.3

數(shù)據(jù)類型2.數(shù)據(jù)類型213.存儲器類型存儲器類型取值范圍data默認存儲器類型,低128字節(jié)內(nèi)部RAM,DATA區(qū)(00H~7FH地址空間),訪問速度最快。bdata可位尋址內(nèi)部RAM,BDATA區(qū)(20H~2FH地址空間),允許位和字節(jié)混合訪問。idata256字節(jié)內(nèi)部RAM,IDATA區(qū)(00H~FFH地址空間),允許訪問全部內(nèi)部單元。pdata分頁尋址外部RAM,PDATA區(qū)(0000H~FFFFH地址空間),用MOVX@Ri指令訪問。xdata外部RAM,XDATA區(qū)(0000H~FFFFH地址空間),用MOVX@DPTR指令訪問。code程序存儲區(qū),CODE區(qū)(0000H~FFFFH地址空間),用MOVC@A+DPTR指令訪問。表5-2KeilC51編譯器支持的存儲器類型對變量定義格式:數(shù)據(jù)類型

[存儲器類型]變量名表;

§5.1.3

數(shù)據(jù)類型3.存儲器類型

例如:unsignedchardatabuffer;22存儲類型的指定:變量或參數(shù)的存儲類型可由存儲模式指定缺省類型,也可由關鍵字code、data、idata、xdata、pdata直接聲明指定。例如:unsigned

char

databuffer;

databuffer;//沒有指定數(shù)據(jù)類型,默認為int型unsigned

char

code

numtab[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xFB,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};

//定義LED顯示字模(參見137頁)unsigned

char

xdata

arr[10][4][4];§5.1.3

數(shù)據(jù)類型3.存儲器類型對變量定義格式:數(shù)據(jù)類型

[存儲器類型]變量名表;

23§5.1.3

數(shù)據(jù)類型3.存儲器類型數(shù)據(jù)存儲類型的指定:變量或函數(shù)參數(shù)存儲類型可由存儲模式

(Small,large,Compact)(OptionsforTarget‘Target1’...選項)指定缺省存儲類型;在small模式下,函數(shù)參數(shù)和局部變量位于由data定義的單片機片內(nèi)數(shù)據(jù)RAM(00~7FH)中;在compact模式下,函數(shù)參數(shù)和局部變量位于pdata定義的擴展數(shù)據(jù)RAM中(訪問用MOVX@Ri)。在large模式下,函數(shù)參數(shù)和局部變量位于xdata定義的擴展數(shù)據(jù)RAM中(訪問用MOVX@DPTR)數(shù)據(jù)存儲模式(Small,large,Compact)24在Xtal(MHz)右側框輸入6,其余按默認設置。4-3匯編語言程序調(diào)試Project窗口,選中Target1,并單擊右鍵,出現(xiàn)浮動菜單。浮動菜單中選中OptionsforTarget‘Target1’...選項。出現(xiàn)OptionsforTarget‘Target1’對話框界面。在該界面中,點擊Target標簽。在該標簽界面中,按下面設置參數(shù):在此設置使用晶振的頻率

針對目標硬件設置工具選項MemoryModel右側下拉選擇:Small,Compact,large的存儲模式。254.關于指針數(shù)據(jù)類型指針變量的值是一個地址,這個地址不僅可以是變量的地址,也可以是其他數(shù)據(jù)結構的地址。KeilC51編譯器支持兩種指針類型:一般指針(GenericPointer)和存儲器指針(MemorySpecificPointer,

指定存儲區(qū)指針)。一般指針的聲明和使用均與標準C相同,同時還可以說明指針的存儲類型(見下頁)。char*s

;/*stringptr*/int*numptr;/*intptr*/§5.1.3

數(shù)據(jù)類型4.關于指針數(shù)據(jù)類型26一般指針的聲明和使用均與標準C相同,同時還可以說明指針的存儲類型。char*s

;/*stringptr*/int*numptr;/*intptr*/可用存儲類型標識符指定一個通用指針的存儲區(qū)如:

char*xdatastrptr;/*genericptrstoredinxdata*/int*datanumptr;/*genericptrstoredindata*/long*idatavarptr;/*genericptrstoredinidata*/這些例子指向可能保存在任何存儲區(qū)中的變量但是指針分別保存在xdata、data和idata中。§5.1.3

數(shù)據(jù)類型4.關于指針數(shù)據(jù)類型27一般指針用3個字節(jié)存放:存儲器類型,存儲器地址高8位偏移量和低8位偏移量。

char

data*str;

//str指向data區(qū)中char型數(shù)據(jù)

int

xdata*pow;

//pow指向外部RAM的int型整數(shù)這種指針存放時,只需1(或2)個字節(jié)就夠了,因只需存放偏移量。

存儲器指針(指定存儲區(qū)指針),說明時即指定了存儲類型,例如:

4.關于指針數(shù)據(jù)類型存儲類型Idata/data/bdatapdataxdataCode編碼值0x000xFE0x010xFF存放數(shù)據(jù)的存儲器類型存儲器類型是在編譯時需要的,既已指出,所以指針只需存偏移量即可,參考:KeilHelp:Cx51CompilerUser'sGuide→LanguageExtensions→Pointers28§5.1.3

數(shù)據(jù)類型4.關于指針數(shù)據(jù)類型象一般指針一樣可指定一個存儲器指針的保存存儲區(qū),即在指針聲明前加存儲類型標識符,例如:unsignedcharxdata

*pt;

//pt本身依存儲模式存放unsignedcharxdata*datapt;//pt被保存在內(nèi)部RAM中unsignedcharxdata

*xdatapt;

//pt被保存在外部RAM中上面的語句都聲明pt為指向保存在外部RAM中unsignedchar數(shù)據(jù)的指針,但pt本身的保存位置卻不同。存儲器指針29運算符是告訴編譯程序執(zhí)行特定算術或邏輯操作的符號,表達式則是由運算符及運算對象所組成的具有特定含義的一個式子。在任意一個表達式的后面加一個分號“;”就構成了一個表達式語句。C51程序就是由多個表達式語句構成的語句集合。運算符可以分為賦值運算符、算術運算符、關系運算符、邏輯運算符、位運算符、復合賦值運算符、逗號運算符、條件運算符、指針和地址運算符、強制類型轉換運算符等?!?.1.4

運算符和表達式301.賦值運算符符號“=”為賦值運算符,它的作用是將一個數(shù)據(jù)的值或表達式的值賦給一個變量。利用賦值運算符將一個變量與一個表達式連接起來的式子成為賦值表達式,在賦值表達式的后面加一個分號“;”便構成了賦值語句。§5.1.4

運算符和表達式1.賦值運算符312.算術運算符算術運算符用于各類數(shù)值運算。包括加(+)、減或取負值(-)、乘(*)、除(/)、取余(或稱模運算,%)、自增(++)、自減(--)共七種。在除法運算中,如果是兩個整數(shù)相除,其結果為整數(shù),舍去小數(shù)部分。用算術運算符將運算對象連接起來的式子就是算術表達式?!?.1.4

運算符和表達式

2.算術運算符32計算一個算術表達式的值時,要按照運算符的優(yōu)先級高低順序進行。算術運算符中,取負值(-)的優(yōu)先級最高,其次是乘法(*)、除法(/)和取余(%)運算符,加法(+)和減法(-)運算符的優(yōu)先級最低。需要時,可在算術表達式中必要的地方采用圓括號來改變優(yōu)先級,括號的優(yōu)先級最高。在使用自增(++)運算符和自減(--)運算符時,要注意運算符的位置。例如,++i和i++的意義完全不同,前者為在使用i之前先使i加1,而后者則是在使用i之后再使i加1。在實際應用中,盡可能使用后者的方式,即i++的形式。§5.1.4

運算符和表達式

2.算術運算符333.關系運算符關系運算符用于比較運算。包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)和不等于(!=)六種。前四種關系運算符具有相同的優(yōu)先級,后兩種關系運算符也具有相同的優(yōu)先級;但前四種的優(yōu)先級高于后兩種。用關系運算符將兩個表達式連接起來即構成關系表達式?!?.1.4

運算符和表達式3.關系運算符344.邏輯運算符邏輯運算符包括與(&&)、或(||)、非(!)3種,用于對包含關系運算符的表達式(稱為條件)進行合并或取非運算。關系運算符和邏輯運算符通常用來判別某個或某些條件是否滿足,條件滿足時結果為1,條件不滿足時結果為0。§5.1.4

運算符和表達式4.邏輯運算符35與運算符(&&)表示2個條件同時滿足時(即2個條件都為真時),返回結果才為真?;蜻\算符(||)用于檢查2個條件中是否有1個為真的運算符,只要有1個條件為真,運算結果就為真。邏輯非運算符(!)表示對表達式的值取反。上述幾種運算符的優(yōu)先級依次為(由高到低):邏輯非→算術運算符→關系運算符→邏輯與→邏輯或?!?.1.4運算符和表達式4.邏輯運算符365.位運算符C語言提供了6種位運算符:按位與(&)、按位或(|)、按位異或(^)、取反(~)、左移(<<)和右移(>>)。位運算符的優(yōu)先級從高到低依次為:按位取反(~)→左移(<<)和右移()→按位與(&)→按位異或(^)→按位或(|)?!?.1.4

運算符和表達式5.位運算符其功能是參與運算的兩數(shù)各對應的二進位進行如下運算:37(1)按位與運算按位與運算符“&”是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相與。只有對應的2個二進位均為1時,結果位才為1,否則為0。(2)按位或運算按位或運算符“|”是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相或。只要對應的2個二進位有1個為1時,結果位就為1?!?.1.4

運算符和表達式5.位運算符38(3)按位異或運算按位異或運算符“^”是雙目運算符。其功能是參與運算的兩數(shù)各對應的二進位相異或。當2個對應的二進位相異時,結果為1。(4)求反運算求反運算符“~”為單目運算符,具有右結合性。其功能是對參與運算的數(shù)的各二進位按位求反?!?.1.4運算符和表達式5.位運算符39(5)左移運算左移運算符“<<”是雙目運算符。其功能把“<<”左邊的運算數(shù)的各二進位全部左移若干位,由“<<”右邊的數(shù)指定移動的位數(shù),高位丟棄,低位補0。(6)右移運算右移運算符“>>”是雙目運算符。其功能是把“>>”左邊的運算數(shù)的各二進位全部右移若干位,“>>”右邊的數(shù)指定移動的位數(shù)。對于有符號數(shù),右移時,符號位將隨同移動。當為正數(shù)時,最高位補0;為負數(shù)時,符號位為1,最高位補1?!?.1.4

運算符和表達式5.位運算符406.復合賦值運算符在賦值運算符“=”之前加上其他二目運算符可構成復合賦值運算符。構成復合賦值表達式的一般形式為:

變量雙目運算符=

表達式它等效于:變量=變量運算符

表達式復合賦值運算符有:+=,-=,*=,/=,%=,<<=,>>=,&=,^=,~=,|=?!?.1.4

運算符和表達式6.復合賦值運算符417.逗號運算符逗號運算符用于把若干表達式組合成一個表達式(稱為逗號表達式)。程序運行時,對于逗號表達式的處理,是從左至右依次計算出各個表達式的值,而整個逗號表達式的值是最右邊表達式的值。例如:inta1,a2,b=2,c=7,d=5;//第1行a1=(++b,c--,d+3);//第2行,a1的值為8a2=++b,c--,d+3;//第3行,

a2的值為4§5.1.4

運算符和表達式

7.逗號運算符428.條件運算符條件運算符(?:)是一個三目運算符,用于條件求值。它要求有三個運算對象,使用它可以將三個表達式連接構成一個條件表達式。條件表達式的一般形式為:邏輯表達式?表達式1:表達式2其功能是,首先計算邏輯表達式的值,當邏輯表達式的值為真(非0值)時,將表達式1的值作為整個條件表達式的值;當邏輯表達式的值為假(0值)時,將表達式2的值作為整個條件表達式的值。§5.1.4

運算符和表達式8.條件運算符439.指針和地址運算符變量的指針就是該變量的地址,而存放變量地址的變量稱為指針變量。為表示指針變量和它所指向的變量地址之間的關系,C語言有運算符:取內(nèi)容(*)和取地址(&),其運算的一般形式分別為:變量=*指針變量指針變量=&目標變量取內(nèi)容(*)運算的含義是將指針變量所指向的目標變量的值賦給等號(=)左邊的變量;取地址(&)運算的含義是將目標變量的地址賦給等號(=)左邊的指針變量?!?.1.4

運算符和表達式

9.指針和地址運算符44unsignedchar*txp;

unsigned

char

txbuffer[50];txp=txbuffer;

例使用指針可以進行外部擴展I/O口的訪問。在C51中有兩種方法訪問外部I/O端口。方法1:使用自定義指針。由于片外I/O端口與片外存儲器統(tǒng)一編址,所以可以定義xdata類型的指針訪問外部I/O端口。例如,某單片機應用系統(tǒng)中,使用8255(見第1版8.3節(jié))擴展I/O端口,采用線選法對8255進行地址譯碼,單片機的P2.7(A15)接8255的片選引腳,因8255的命令口地址為7FF3H,PA口地址為7FF0H,PB口地址為7FF1H,PC口地址為7FFF2H。訪問8255的C程序如下:§5.1.4

運算符和表達式9.指針和地址運算符458255因目前停產(chǎn)較少用,本版教材不再介紹(用法見第1版8.3節(jié))方法1:使用自定義指針訪問外部擴展I/O口寫端口程序:charxdata

*com8255;

//定義指向外部存儲區(qū)(片外I/O端口)的指針

com8255=0x7ff3;

//使指針指向8255的控制口(命令口)地址7FF3H*com8255=0x81;//輸出命令字81H到命令口寄存器//

81H:PA,PB口都是模式0,直接輸出,PC口直接輸入以上C程序相當于下面的匯編語言程序:

MOVDPTR,#7FF3H

MOVA,#81H

MOVX@DPTR,A具體命令介紹見見第1版8.3節(jié):并行接口擴展方法,309頁圖8-5246方法1:使用自定義指針訪問外部擴展I/O口讀端口程序:

charxdata*com8255;//定義指針

chari;com8255=0x7FF0;

//使指針指向8255的PA口地址7FF0Hi=*com8255;//讀PA端口內(nèi)容到變量i47§5.1.4

運算符和表達式9.指針和地址運算符為了方便訪問外部存儲器及I/O端口,在C51的absacc.h頭文件做了如下定義,利用這些定義可以方便地訪問外部I/O端口。#defineCBYTE((unsignedcharvolatile

code*)0)#defineDBYTE((unsignedcharvolatile

data*)0)#definePBYTE((unsignedcharvolatile

pdata*)0)#defineXBYTE((unsignedcharvolatile

xdata*)0)volatile修飾了的變量隨程序的執(zhí)行其值會被改變,“易變”方法2:使用C51預定義指針訪問外部擴展I/O口48#defineXBYTE((unsignedcharvolatilexdata*)0)以XBYTE為例介紹上述宏定義使用方法,XBYTE使用格式:

XBYTE[地址]方法2:使用C51預定義指針訪問外部擴展I/O口例如:#include<absacc.h>#define

PORTA

XBYTE[0x7ff0]

//其中,PORTA為程序定義的I/O端口名稱,[]內(nèi)的內(nèi)容//7ff0H為PORTA的地址voidmain(void){chara;

PORTA=0x81;//*輸出81H到端口7ff0Ha=PORTA;//讀端口7ff0H到變量a}定義XBYTE數(shù)組的首地址是0XBYTE[0x7ff0]的中括號內(nèi)的值0x7ff0,指出了(定義)數(shù)組XBYTE首地址的偏移地址4910.強制類型轉換運算符強制類型轉換運算符的作用是將表達式或變量的類型強制轉換成為括號內(nèi)所指定的類型。強制類型轉換運算符的一般使用形式為:變量=(類型)表達式如:pxdata=(charxdata*)0x3000;//pxdata為在xdata中定義的char類型指針變量§5.1.4運算符和表達式10.強制類型轉換運算符50表達式語句是最基本的一種語句。在表達式的后面加一個分號“;”就構成了表達式語句。表達式語句也可以僅由一個分號“;”構成,這種語句稱為空語句??照Z句不執(zhí)行具體的動作。程序設計時,有時需要用到空語句。例如,使用循環(huán)語句延時程序中的循環(huán)體內(nèi)可以使用空語句?!?.2KeilC51程序的語句§5.2.1表達式語句51條件語句又稱為分支語句,使用關鍵字“if”構成。C51提供了三種形式的條件語句。1.if(條件表達式){語句體;}§5.2.2條件語句522.if(條件表達式){

語句體1;}else{

語句體2;}3.if(條件表達式1){

語句體1;}elseif(條件表達式2){

語句體2;}……elseif(條件表達式m){

語句體m;}Else{

語句體n;}§5.2.2條件語句53開關語句也是一種用來實現(xiàn)多條件分支的語句?!璫ase常量表達式n:語句體n;

break;

default:語句體d}§5.2.3開關語句54switch(表達式){case常量表達式1:語句體1;

break;

case常量表達式2:語句體2;

break;1.while語句利用while語句構成循環(huán)結構的一般形式如下:while(條件表達式){

語句體;}§5.2.4循環(huán)語句552.do-while語句采用do-while語句構成循環(huán)結構的一般形式如下:do{

語句體;}while(條件表達式);3.for語句采用for語句構成循環(huán)結構的一般形式如下:for([初值設定表達式];[循環(huán)條件表達式];[更新表達式]){

語句體;}§5.2.4循環(huán)語句56goto語句是一個無條件轉向語句,其一般形式為:goto語句標號;break語句也可以用于跳出循環(huán)語句,其一般形式為:break;continue是一種中斷語句,其功能是中斷本次循環(huán),繼續(xù)下一次循環(huán),一般形式為:continue;return語句用于終止函數(shù)的執(zhí)行,并控制程序返回到調(diào)用該函數(shù)的位置。一般形式為:return(表達式);return;§5.2.5goto、break、continue和return語句57兩種函數(shù):KeilC51定義的標準庫函數(shù)和用戶自定義函數(shù)?!?.3.1函數(shù)的定義與調(diào)用§5.3函數(shù)58函數(shù)定義的一般形式為:函數(shù)返回值類型

函數(shù)名(形式參數(shù)表){

局部變量定義

函數(shù)體語句}函數(shù)調(diào)用的一般形式為:[變量=]函數(shù)名(實際參數(shù)表)5.3.2KeilC51函數(shù)C51的函數(shù)聲明對ANSIC作了擴展,具體包括:1、中斷函數(shù)聲明中斷函數(shù)通過使用interrupt關鍵字和中斷號(0~31)來聲明。中斷號告訴編譯器中斷服務程序入口地址。IAP15W4K58S4單片機的中斷號及中斷服務程序入口地址如表5-3

中斷號中斷源入口地址中斷號中斷源入口地址0外部中斷INT00003H11外部中斷

INT3005BH1T0溢出中斷000BH12T2溢出中斷0063H2外部中斷INT10013H16外部中斷

INT40083H3T1溢出中斷001BH17串口3中斷008BH4串行口UART1中斷0023H18串口4中斷0093H5ADC中斷002BH19T3溢出中斷009BH6LVD中斷0033H20T4溢出中斷3H7PCA中斷003BH21比較器中斷00ABH8串行口UART2中斷0043H22PWM中斷00B3H9SPI中斷004BH23PWM異常檢測中斷00BBH10外部中斷

INT20053H59中斷服務函數(shù)的一般形式為:void

函數(shù)名(void)interrupt中斷號

[usingn]中斷函數(shù)通過使用interrupt關鍵字和中斷號來聲明。中斷號告訴編譯器中斷服務程序的入口地址。也就是說,C51通過中斷號來區(qū)分各個不同的中斷,而與中斷函數(shù)的名字無關。其中usingn用于選擇單片機不同的寄存器組,n為0~3的常整型數(shù),分別選中4個不同寄存器組中的一個。Using是一個可選項,可以不用。不用時,由編譯器自動選擇一個寄存器組。60/785.3.2KeilC51函數(shù)1、中斷函數(shù)聲明5.3.2KeilC51函數(shù)1、中斷函數(shù)聲明例如,串行口1的中斷函數(shù)(4號中斷)可以聲明如下:

voidUART1_ISR(void)interrupt4[using1]{/*中斷服務程序的代碼*/}上述代碼聲明了串行口1中斷服務函數(shù)。其中,interrupt4指明是串行口1的中斷,using1指明采用工作寄存器區(qū)1區(qū),using1在中括號中,說明該部分可省略。其他中斷函數(shù)的定義與此類似。中斷函數(shù)具體是哪個中斷的函數(shù),與中斷號有關,而與函數(shù)名(如UART1_ISR)無關

,但一般賦予與相應中斷相符合的名稱。無輸入?yún)?shù)無返回參數(shù)615.3.2KeilC51函數(shù)-——2、指定工作寄存器區(qū)當需要指定函數(shù)中使用的工作寄存器區(qū)時,使用關鍵字using后跟一個0到3的數(shù),對應著工作寄存器0到3區(qū)。例如,在下面的函數(shù)中使用了工作寄存器1區(qū)(相當于PSW.4=0,PSW.3=1):

unsignedcharGetKey(void)using1{/*用戶程序代碼*/}

指定工作寄存器區(qū)62程序狀態(tài)標志寄存器PSW(8位)RS1,RS0(PSW.4~PSW.3):工作寄存器組選擇控制位,其詳細介紹見后續(xù)內(nèi)容。OV(PSW.2):溢出標志位。指示運算過程中是否發(fā)生了溢出,在執(zhí)行指令過程中自動形成。位號D7D6D5D4D3D2D1D0符號CYACF0RS1RS0OVF1PRS1RS0OVP(PSW.0):奇偶標志位累加器ACC中1的個數(shù)為偶數(shù),P=0;否則P=1。每個指令周期都由硬件來置“1”或清“0”。在具有奇偶校驗的串行數(shù)據(jù)通信中,可根據(jù)P設置奇偶校驗位。P63工作寄存器組的選擇:PSW寄存器中的RS1和RS0兩位組合決定當前使用的工作寄存器組??赏ㄟ^位操作指令修改RS1和RS0的內(nèi)容,選擇不同的工作寄存器組。RS1(PSW.4)RS0(PSW.3)工作寄存器組工作寄存器地址000R7~R0對應的地址為07H~00H011R7~R0對應的地址為0FH~08H102R7~R0對應的地址為17H~10H113R7~R0對應的地址為1FH~18H表3-1工作寄存器組選擇18H~1FH10H~17H08H~0FH00H~07H3區(qū)(R7~R0)2區(qū)(R7~R0)1區(qū)(R7~R0)0區(qū)(R7~R0)645.3.2KeilC51函數(shù)——2、指定存儲模式用戶可以使用small,compact及l(fā)arge說明存儲模式。例如:

voidfun1(void)small{}提示:small說明的函數(shù)內(nèi)部變量全部使用內(nèi)部RAM。關鍵的、經(jīng)常性的、耗時的地方可以這樣聲明,以提高運行速度。2、指定存儲模式65用compact說明時,函數(shù)參數(shù)和局部變量位于pdata定義的擴展數(shù)據(jù)RAM中。用large說明時,函數(shù)參數(shù)和局部變量位于xdata定義的擴展數(shù)據(jù)RAM中。5.3.2KeilC51函數(shù)——3、函數(shù)的重入一個可重入函數(shù),簡單來說,就是可以被中斷的函數(shù),即可以在這個函數(shù)執(zhí)行的任何時刻中斷它,可重入函數(shù)可以被遞歸調(diào)用。遞歸或可重入函數(shù)在單片機系統(tǒng)中容易產(chǎn)生問題,因為單片機和PC不同,PC使用(調(diào)用)堆棧傳遞參數(shù),且靜態(tài)變量以外的內(nèi)部變量都在堆棧中;而單片機一般使用寄存器傳遞參數(shù),

內(nèi)部變量一般在固定的RAM中,函數(shù)重入時會破壞(覆蓋)上次調(diào)用的數(shù)據(jù)??稍诤瘮?shù)前聲明函數(shù)的不可重入性(不可中斷性)。若聲明為不可重入(中斷)的,則該函數(shù)調(diào)用過程中將不可被中斷。typedefunsignedcharuchar;#pragmadisable/*DisableInterrupts*/uchardfunc(ucharp1,ucharp2){return(p1*p2+p2*p1);}66(#pragma的作用是設定編譯器的狀態(tài)或者指示編譯器完成一些特定的動作)5.3.2KeilC51函數(shù)——3、函數(shù)的重入可用以下兩種方法解決函數(shù)的重入(及不可中斷)問題:第一種方法:

在相應的函數(shù)前使用“#pragmadisable”聲明,即只允許主程序或中斷之一調(diào)用該函數(shù)(函數(shù)調(diào)用后不再被中斷)。第二種方法:

將該函數(shù)說明為可重入的。如下:

voidfunc(param...)reentrant{...};因為單片機內(nèi)部堆??臻g的限制,C51沒有像大系統(tǒng)那樣使用調(diào)用堆棧:一般在C語言中調(diào)用過程時,會把過程的參數(shù)和過程中使用的局部變量入棧。KeilC51編譯后將生成一個可重入變量堆棧,然后就可以模擬通過調(diào)用堆棧傳遞變量的方法。67這樣函數(shù)重入時,不用擔心變量數(shù)據(jù)被覆蓋的問題。

5.3.2KeilC51函數(shù)——3、函數(shù)的重入為了提高效率,C51沒有提供這種調(diào)用堆棧,而是提供一種壓縮棧。每個過程被給定同一個空間,用于存放局部變量。過程中的每個變量都存放在這個空間的固定位置。當遞歸調(diào)用這個過程時,會導致變量被覆蓋。在某些實時應用中,非重入函數(shù)是不可取的。因為,函數(shù)調(diào)用時可能會被中斷程序中斷,而在中斷程序中可能再次調(diào)用這個函數(shù),所以C51允許將函數(shù)定義成重入函數(shù)。重入函數(shù)可被遞歸調(diào)用和多重調(diào)用,而不用擔心變量被覆蓋,因C51可模擬生成一個可重入變量堆棧{隨存儲模式(small,compact,large)不同,堆??稍诓煌拇鎯ζ鲄^(qū)(idata,pdata,xdata)},每次函數(shù)調(diào)用時的局部變量都會被單獨保存。因為這些堆棧是模擬的,重入函數(shù)一般都比較大,運行起來也比較慢。不常使用685.3.2KeilC51函數(shù)——3、函數(shù)的重入由于一般可重入函數(shù)由主程序和中斷調(diào)用(即遞歸調(diào)用),所以通常中斷程序使用與主程序不同的工作寄存器組。另外,對可重入函數(shù),在相應的函數(shù)前面加上開關#pragmanoaregs,以禁止編譯器使用絕對寄存器尋址,可生成不依賴于寄存器組的代碼。所以對不依賴于寄存器組的函數(shù)可被其他使用了不同的寄存器組的多個函數(shù)調(diào)用。externcharfunc();#pragmaNOAREGSnoaregfunc

()

{k=func()+func();}#pragmaAREGSaregfunc()using3

{k=noaregfunc()+func();

}不常使用69本征庫函數(shù)是指編譯時直接將固定的代碼插入到當前行,而不是用匯編語言中的ACALL和LCALL指令實現(xiàn)調(diào)用,從而大大提高函數(shù)的訪問效率。非本征庫函數(shù)則必須由ACALL和LCALL指令實現(xiàn)調(diào)用。KeilC51提供了9個本征庫函數(shù),如表5-4所示。使用本征庫函數(shù)時,須在源程序中包含頭文件(含有函數(shù)原型聲明),即用預處理命令#include<INTRINS.H>?!?.4.1本征庫函數(shù)§5.4KeilC51庫函數(shù)70函數(shù)名及定義功能說明unsignedchar_crol_(unsignedcharval,unsignedcharn)將字符型數(shù)據(jù)val循環(huán)左移n位,相當于RL指令。unsignedint_irol_(unsignedintval,unsignedcharn)將整型數(shù)據(jù)val循環(huán)左移n位,相當于RL指令。unsignedlong_lrol_(unsignedlongval,unsignedcharn)將長整型數(shù)據(jù)val循環(huán)左移n位,相當于RL指令。unsignedchar_cror_(unsignedcharval,unsignedcharn)將字符型數(shù)據(jù)val循環(huán)右移n位,相當于RR指令。unsignedint_iror_(unsignedintval,unsignedcharn)將整型數(shù)據(jù)val循環(huán)右移n位,相當于RR指令。unsignedlong_lror_(unsignedlongval,unsignedcharn)將長整型數(shù)據(jù)val循環(huán)右移n位,相當于RR指令。bit_testbit_(bitx)相當于JBCbit指令unsignedchar_chkfloat_(floatval)測試并返回浮點數(shù)狀態(tài)。void_nop_(void)產(chǎn)生一個NOP指令。表5-4KeilC51編譯器提供的本征庫函數(shù)§5.4.1

本征庫函數(shù)71_chkfloat_函數(shù)返回一個unsignedchar值包含下面的狀態(tài)信息:返回值意義0

標準浮點數(shù)1

浮點數(shù)02+INF正溢出3-INF負溢出4NaN(不是一個數(shù))錯誤狀態(tài)§5.4KeilC51庫函數(shù)5.4.2字符判斷轉換庫函數(shù)(表5-5)72字符判斷轉換庫函數(shù)的原型聲明在頭文件CTYPE.H中定義。函數(shù)名及定義功能說明bit

isalpha(char

c)檢查參數(shù)字符是否為英文字母,是則返回1,否則返回0bit

isalnum(char

c)檢查參數(shù)字符是否為英文字母或數(shù)字字符,是則返回1,否則返回0bit

iscntrl(char

c)檢查參數(shù)字符是否為控制字符(值在0x00~0x1f之間或等于0x7f)是則返回1,否則返回0bit

isdigit(char

c)檢查參數(shù)字符是否為十進制數(shù)字0~9,是則返回1,否則返回0bit

isgraph(char

c)檢查參數(shù)字符是否為可打印字符(不包括空格),值域0x21~0x7e,是則返回1,否則返回0bit

isprint(char

c)檢查參數(shù)字符是否為可打印字符(包括空格),值域0x20~0x7e,是則返回1,否則返回0bit

ispunct(char

c)檢查參數(shù)字符是否為標點、空格或格式字符,是則返回1,否則返回0bit

islower(char

c)檢查參數(shù)字符是否為小寫英文字母,是則返回1,否則返回0bit

isupper(char

c)檢查參數(shù)字符是否為大寫英文字母,是則返回1,否則返回0bit

isspace(char

c)檢查參數(shù)字符是否為空格、制表符、回車、換行、垂直制表符和送紙(值為0x09~0x0d,或為0x20),是則返回1,否則返回0bit

isxdigit(char

c)檢查參數(shù)字符是否為十六進制數(shù)字字符,是則返回1,否則返回0char

toint(char

c)將ASCII字符的0~9、a~f(大小寫無關)轉換為十六進制數(shù)字,返回值為0H~9H,0AH~0FHchar

tolower(char

c)將大寫字符轉換成小寫形式,如果字符參數(shù)不在A~Z之間,則該函數(shù)不起作用char

_tolower(char

c)將字符參數(shù)c與常數(shù)0x20逐位相或,從而將大寫字符轉換成小寫字符char

toupper(char

c)將小寫字符轉換成大寫形式,如果字符參數(shù)不在a~z之間,則該函數(shù)不起作用char

_toupper(char

c)將字符參數(shù)c與常數(shù)0xdf逐位相與,從而將小寫字符轉換成大寫字符char

toascii(char

c)將任何字符參數(shù)值縮小到有效的ASCII范圍內(nèi),即將c與0x7f相與,去掉第7位以上的位§5.4KeilC51庫函數(shù)5.4.2字符判斷轉換庫函數(shù)(表5-5)73函數(shù)名及定義功能說明bit

isupper(char

c)檢查參數(shù)字符是否為大寫英文字母,是則返回1,否則返回0bit

isspace(char

c)檢查參數(shù)字符是否為空格、制表符、回車、換行、垂直制表符和送紙(值為0x09~0x0d,或為0x20),是則返回1,否則返回0bit

isxdigit(char

c)檢查參數(shù)字符是否為十六進制數(shù)字字符,是則返回1,否則返回0char

toint(char

c)將ASCII字符的0~9、a~f(大小寫無關)轉換為十六進制數(shù)字,返回值為0H~9H,0AH~0FHchar

tolower(char

c)將大寫字符轉換成小寫形式,如果字符參數(shù)不在A~Z之間,則該函數(shù)不起作用char

_tolower(char

c)將字符參數(shù)c與常數(shù)0x20逐位相或,從而將大寫字符轉換成小寫字符char

toupper(char

c)將小寫字符轉換成大寫形式,如果字符參數(shù)不在a~z之間,則該函數(shù)不起作用char

_toupper(char

c)將字符參數(shù)c與常數(shù)0xdf逐位相與,從而將小寫字符轉換成大寫字符char

toascii(char

c)將任何字符參數(shù)值縮小到有效的ASCII范圍內(nèi),即將c與0x7f相與,去掉第7位以上的位(續(xù)表)表5-6輸入/輸出庫函數(shù)§5.4KeilC51庫函數(shù)5.4.3輸入/輸出庫函數(shù)(表5-6)74函數(shù)名及定義功能說明char

_getkey(void)等待從8051串口讀入一個字符并返回讀入的字符,這個函數(shù)是改變整個輸入端口機制時應做修改的唯一一個函數(shù)char

getchar(void)使用_getkey從串口讀入字符,并將讀入的字符馬上傳給putchar函數(shù)輸出,其他與_getkey函數(shù)相同char

*gets(char

*s,int

n)該函數(shù)通過getchar從串口讀入一個長度為n的字符串并存入由s指向的數(shù)組。輸入時一旦檢測到換行符就結束字符輸入。輸入成功時返回傳入的參數(shù)指針,失敗時返回NULLchar

ungetchar(char

c)將輸入字符回送到輸入緩沖區(qū),因此下次gets或getchar可用該字符。成功時返回char型值,失敗時返回EOF,不能處理多個字符char

putchar(char

c)通過8051串行口輸出字符,與函數(shù)_getkey一樣,這是改變整個輸出機制所需要修改的唯一一個函數(shù)int

printf(const

char

*fmstr[,argument]...)以第一個參數(shù)指向字符串制定的格式通過8051串行口輸出數(shù)值和字符串,返回值為實際輸出的字符數(shù)int

sprintf(char

*s,const

char

*fmstr[,argument]...)與printf功能相似,但數(shù)據(jù)是通過一個指針s送入內(nèi)存緩沖區(qū),并以ASCII碼的形式存儲int

puts(const

char

*s)利用putchar函數(shù)將字符串和換行符寫入串行口,錯誤時返回EOF,否則返回0int

scanf(const

char

*fmstr[,argument]...)在格式控制串的控制下,利用getchar函數(shù)從串行口讀入數(shù)據(jù),每遇到一個符合格式控制串fmstr規(guī)定的值,就將它按順序存入由參數(shù)指針argument指向的存儲單元。其中每個參數(shù)都是指針,函數(shù)返回所發(fā)現(xiàn)并轉換的輸入項數(shù),錯誤則返回EOFint

sscanf(char

*s,const

char

*fmstr[,argument]...)與scanf的輸入方式相似,但字符串的輸入不是通過串行口,而是通過指針s指向的數(shù)據(jù)緩沖區(qū)void

vprintf(const

char

*s,char

*fmstr,char

*argptr)將格式化字符串和數(shù)據(jù)值輸出到由指針s指向的內(nèi)存緩沖區(qū)內(nèi)。類似于sprintf,但接受一個指向變量表的指針,而不是變量表。返回值為實際寫入到輸出字符串中的字符數(shù)表5-6輸入/輸出庫函數(shù)(續(xù)表)§5.4KeilC51庫函數(shù)5.4.3輸入/輸出庫函數(shù)(表5-6)75函數(shù)名及定義功能說明int

sprintf(char

*s,const

char

*fmstr[,argument]...)與printf功能相似,但數(shù)據(jù)是通過一個指針s送入內(nèi)存緩沖區(qū),并以ASCII碼的形式存儲int

puts(const

char

*s)利用putchar函數(shù)將字符串和換行符寫入串行口,錯誤時返回EOF,否則返回0int

scanf(const

char

*fmstr[,argument]...)在格式控制串的控制下,利用getchar函數(shù)從串行口讀入數(shù)據(jù),每遇到一個符合格式控制串fmstr規(guī)定的值,就將它按順序存入由參數(shù)指針argument指向的存儲單元。其中每個參數(shù)都是指針,函數(shù)返回所發(fā)現(xiàn)并轉換的輸入項數(shù),錯誤則返回EOFint

sscanf(char

*s,const

char

*fmstr[,argument]...)與scanf的輸入方式相似,但字符串的輸入不是通過串行口,而是通過指針s指向的數(shù)據(jù)緩沖區(qū)void

vprintf(const

char

*s,char

*fmstr,char

*argptr)將格式化字符串和數(shù)據(jù)值輸出到由指針s指向的內(nèi)存緩沖區(qū)內(nèi)。類似于sprintf,但接受一個指向變量表的指針,而不是變量表。返回值為實際寫入到輸出字符串中的字符數(shù)輸入/輸出庫函數(shù)的原型聲明在頭文件STDIO.H,通過8051內(nèi)核單片機的串行口工作,若希望支持其他I/O接口,只需改動_getkey()和putchar(),庫中所有其他I/O支持函數(shù)都依賴于這兩個函數(shù)模塊。在使用8051系列單片機的串行口之前,應先對其進行初始化。例,晶振頻率11.0592MHz,若串口1通信的參數(shù)為9600,n,8,1(9600波特率,8個數(shù)據(jù)位,1個停止位,沒有奇偶校驗位),則初始化語句:voidUartInit(void)//9600bps@11.0592MHz{SCON=0x50;//8位數(shù)據(jù),可變波特率AUXR&=0xBF;//定時器1時鐘為Fosc/12,即12TAUXR&=0xFE;//串口1選擇定時器1為波特率發(fā)生器TMOD&=0x0F;//設定定時器1為16位自動重裝方式TL1=0xE8;//設定定時初值TH1=0xFF;//設定定時器初值ET1=0;//禁止定時器1中斷TR1=1;//啟動定時器1TI=1;//直接使用printf必須加入此句才能實現(xiàn)發(fā)送

}§5.4KeilC51庫函數(shù)5.4.3輸入/輸出庫函數(shù)(表5-6略)76例如:_getkey()函數(shù)的定義(在Keil安裝文件夾LIB的C文件中)#include<reg51.h>char_getkey(){charc;while(!RI);

c=SBUF;RI=0;return(c);}【例5-1】輸出庫函數(shù)printf()的應用舉例:#include<stdio.h>#include<stc15.h>voidUart1Init(void);//將前面定義的串口1初始化函數(shù)進行聲明voidmain(void){ chara; intb; longc; unsignedcharx; unsignedinty; unsignedlongz; floatf,g; charbuf[]="TestString"; char*p=buf;

Uart1Init();

//調(diào)用串口1初始化函數(shù)

a=1;b=12365;c

溫馨提示

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

評論

0/150

提交評論