當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]1 編譯器支持的數(shù)據(jù)類型1.1 C-51 編譯器支持下列數(shù)據(jù)類型:數(shù) 據(jù) 類 型長(zhǎng) 度值 域bit1 字節(jié)0 或 1signed char1 字節(jié)-128~+127unsigned char1 字節(jié)0~255signed int2 字節(jié)-32768~+32867unsigned int2 字節(jié)0~65535s

1 編譯器支持的數(shù)據(jù)類型

 

1.1 C-51 編譯器支持下列數(shù)據(jù)類型:

 

 

 

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

 

長(zhǎng) 度

 

值 域

 

bit

 

1 字節(jié)

 

0 或 1

 

signed char

 

1 字節(jié)

 

-128~+127

 

unsigned char

 

1 字節(jié)

 

0~255

 

signed int

 

2 字節(jié)

 

-32768~+32867

 

unsigned int

 

2 字節(jié)

 

0~65535

 

signed long

 

4 字節(jié)

 

-2147483648~+2147483647

 

unsigned long

 

4 字節(jié)

 

0~4294967295

 

float

 

4 字節(jié)

 

±1.176E-38~±3.40E+38

 

指針

 

1~3 字節(jié)

 

對(duì)象地址

 

sbit

 

1 位

 

0 或 1

 

sfr

 

1 字節(jié)

 

0~255

 

sfr16

 

2 字節(jié)

 

0~65535

 

 

 

編譯的數(shù)據(jù)類型(如結(jié)構(gòu))包含上表所列的數(shù)據(jù)類型。由于8051系列是8位機(jī),因而不存在字節(jié)校準(zhǔn)問(wèn)題。這意味著數(shù)據(jù)結(jié)構(gòu)成員是順序放置的。

數(shù)據(jù)類型的轉(zhuǎn)換:當(dāng)計(jì)算結(jié)果隱含著另外一種數(shù)據(jù)類型時(shí),數(shù)據(jù)類型可以自動(dòng)進(jìn)行轉(zhuǎn)換,例如,將一個(gè)位變量賦給一個(gè)整型變量時(shí),位型值自動(dòng)轉(zhuǎn)換為整型值,有符號(hào)變量的符號(hào)也能自動(dòng)進(jìn)行處理。這些轉(zhuǎn)換也可以用C語(yǔ)言的標(biāo)準(zhǔn)指令進(jìn)行人工轉(zhuǎn)換。

1.2 數(shù)據(jù)類型的物理結(jié)構(gòu)

1.2.1 bit

 

 

“bit”類型只有1位,不允許有位指針和位數(shù)組。位對(duì)象始終位于8051 CPU的可尋址RAM空間。如果程序控制流允許,L51將位對(duì)象交迭。

 

1.2.2 signed/unsigned char;data/idata/pdata 指針

“char”類型標(biāo)量和基于存貯器的“data/idata/pdata”指針具有1個(gè)字節(jié)長(zhǎng)度(8 bits)。

1.2.3 signed/unsigned int/short;xdata/code 指針

“int”和“short”類型標(biāo)量及指向xdata/code區(qū)域的指針具有2字節(jié)長(zhǎng)度(16

bits)。

整型值(或偏移)0x1234以下面方式保存在內(nèi)存中:

地址: +0 +1

內(nèi)容: 0x12 0x34

1.2.4 signed/unsigned long

“long”類型標(biāo)量長(zhǎng)為4個(gè)字節(jié)(32 bits),值0x12345678以下面方式放置:

地址: +0 +1 +2 +3

內(nèi)容: 0x12 0x34 0x56 0x78

 

1.2.5 “一般”指針

“一般”指針包括3個(gè)字節(jié):2字節(jié)偏移和1字節(jié)存貯器類型:

地址: +0 +1 +2

內(nèi)容: 存貯器類型 偏移高位 偏移低位

第一個(gè)字節(jié)代表了指針的存貯器類型,存貯器類型編碼如下:

存貯器類型 IDATA XDATA PDATA DATA CODE

值 1 2 3 4 5

使用其它類型值可能導(dǎo)致不可預(yù)測(cè)的程序動(dòng)作。

XDATA類型的0x1234地址作為指針表示如下:

地址: +0 +1 +2

內(nèi)容: 0x02 0x12 0x34

 

當(dāng)用常數(shù)作指針時(shí),必須注意正確定義存貯器類型和偏移。下例將值0x41寫入絕對(duì)地址為0x8000的外部數(shù)據(jù)存貯器:

#define XBYTE ((char *)0x20000L)

XBYTE[0x8000]=0x41;

上例中用其它常數(shù)索引或索引變量也起作用。這樣,各種存貯器類型的絕對(duì)地址可以一種非常有效的方式訪問(wèn)。但有一個(gè)例外,即SFR。

 

注意:絕對(duì)地址定義為“long”型常量,低16位包含偏移,高8位表明了xdata類型。為了表示這種指針,必須用長(zhǎng)整數(shù)來(lái)定義存貯器類型。

C51編譯器不檢查指針常數(shù),用戶必須選擇有實(shí)際意義的值。

 

1.2.6 float

“float”類型為4個(gè)字節(jié)(32位),使用的格式與IEEE-754標(biāo)準(zhǔn)(32位)具有24位精度,尾數(shù)的高位始終為“1”,因而不保存,位的分布如下:

l 1位符號(hào)

l 8位指數(shù)位

l 23位尾數(shù)

符號(hào)位是最高位,尾數(shù)為最低的位,內(nèi)存中按字節(jié)存貯如下:

地址: +0 +1 +2 +3

內(nèi)容: MMMM MMMM MMMM MMMM E MMM MMMM S EEE EEEE

其中: S:符號(hào)位,1=負(fù),0=正

E:指數(shù)(在兩個(gè)字節(jié)中),偏移為127

M:23位尾數(shù),最高位“1”

浮點(diǎn)值——12.5的十六進(jìn)制為0xC1480000,它按下面方式存貯:

地址: +0 +1 +2 +3

內(nèi)容: 0x00 0x00 0x48 0xc1

8051不包括捕獲浮點(diǎn)錯(cuò)誤(例外)的中斷向量。用戶軟件因此必須對(duì)錯(cuò)誤條件作出適當(dāng)反應(yīng)。下面推薦一種方法(也可以用其它可靠辦法):“union”用來(lái)保存浮點(diǎn)值,這個(gè)“union”必須包括一個(gè)“float”和一個(gè)“unsigned long”,以根據(jù)IEEE對(duì)錯(cuò)誤作出響應(yīng)。除了通常浮點(diǎn)值外,IEEE標(biāo)準(zhǔn)可能出錯(cuò)的條件以下面二進(jìn)制值表示,為檢查可能出現(xiàn)的計(jì)算錯(cuò)誤,可在計(jì)算后進(jìn)行檢查。因?yàn)楫?dāng)執(zhí)行一個(gè)運(yùn)算時(shí)考慮了每個(gè)運(yùn)算符的錯(cuò)誤狀態(tài)并且該狀態(tài)被送到結(jié)果中。

NaN 0xFFFFFFF 不是一個(gè)數(shù)

+INF 0x7F80000 正無(wú)窮(正溢出)

-INF 0XFF80000 負(fù)無(wú)窮(負(fù)溢出)

1.3 C-51 的擴(kuò)充定義

1.3.1 特殊功能寄存器的聲明

MSC-51 系列包括多種寄存器,其中一些具有特殊功能,如定時(shí)器,端口的控制寄存器等,為了能夠直接訪問(wèn)這些寄存器,C51編譯器提供了一種定義的自主形式,這是必要的,因?yàn)檫@些定義與標(biāo)準(zhǔn)C語(yǔ)言是不兼容的。

為了支持這些特殊功能寄存器(SFR)的聲明,引入了關(guān)鍵詞“sfr”,語(yǔ)法如下:

sfr-dcl:sfr sfr_name=int_constant

例:

sfr p0=0x80;

sfr p1=0x90;

必須注意的是“sfr”后不是一個(gè)地址而是一個(gè)名字。因此上例中名字P0和P1(port0和port1)定義為特殊功能寄存器并被賦予相應(yīng)的絕對(duì)地址,名字可按意愿自由選取,源文件中不應(yīng)有先定義的sfr名字。

“=”號(hào)后的地址必須是常數(shù),不允許帶有運(yùn)算符的表達(dá)式,這個(gè)常數(shù)表達(dá)式必須在特殊功能寄存器的地址范圍內(nèi),位于0X80到0XFF之間。

8051系列寄存器數(shù)量和類型是極其不同的,因此建議將所有特別的“sfr”聲明放入一個(gè)頭文件,頭文件包括8051一些系列成員中的SFR定義。進(jìn)一步的定義可由用戶用一文件編輯器產(chǎn)生。

 

1.3.2 對(duì)SFR的16位數(shù)據(jù)訪問(wèn)

在新的8051系列產(chǎn)品中,SFR在功能上經(jīng)常組合為16位的,為了有效的訪問(wèn)這類SFR,使用定義“sfr16”,當(dāng)“SFR”的高端直接位于低端后時(shí),對(duì)SFR16位的訪問(wèn)是可能的。例如8052的定時(shí)器2就是這種情況,16位聲明的語(yǔ)法與“sfr”相同,SFR低地址部分必須作為sfr16的地址:

例:sfr16 T2=0xCC /*Timer2:T2L=0CCH,T2H=0CDH */

sfr16 RCAP2=0xCA /*RCAP2L=0CAH,PCAP2H=0CBH */

本例中,T2(由T2L和T2H組成)和RCAP2(由RCAP2L和RCAP2H組成)被定義為16位SFR,即使在這種情況下,聲明中的名字后仍不是賦值語(yǔ)句,而是一個(gè)SFR地址,高字節(jié)必須直接位于低字節(jié)之后,這種聲明適用于所有新的SFR,但不能用于Timer0和Timer1。

 

1.3.3 SBIT:特殊功能位聲明

在典型的8051應(yīng)用問(wèn)題中,經(jīng)常需要單獨(dú)訪問(wèn)SFR中的位,C51擴(kuò)充功能使之成為可能,特殊位,象SFR一樣,不與標(biāo)準(zhǔn)C語(yǔ)言兼容,使用保留字“sbit”可訪問(wèn)位尋址對(duì)象。與SFR聲明一樣,用保留字“sbit”聲明某些特殊位接受符號(hào)名,“=”后語(yǔ)句將絕對(duì)值地址賦給變量名,這種地址分配有三種方法:

方法1:sfr_name^int_constant

當(dāng)字節(jié)是特殊功能寄存器的地址可用這個(gè)方法。sfr_name必須是已定義的SFR的名字,“^”后的語(yǔ)句定義了基地址上的特殊位的位置,該位置必須是一個(gè)0~7的數(shù)。

例: sfr PSW="0xD0";

sfr LE="0xA8";

sbit OV="PSW"^2;

sbit CY="PSW"^7;

方法2:int_constant^int_constant

這種方法以一整常數(shù)作基地址,該值必須在0x80~0xFF之間,并能被8整除,確定位的位置方法同上。

例: sbit OV="0xD0"^2;

sbit CV="0xD0"^7;

sbit EA="0xA8"^7;

方法3: int_constant

這種方法是將位的絕對(duì)地址賦給變量,地址必須位于0x80~0xFF之間。

例: sbit OV="0xD2";

sbit CY="0xD7";

sbit EA="0xAF";

特殊功能位代表了一個(gè)獨(dú)立的聲明類,它不能與其它聲明和位域互換。

 

1.3.4 BIT:位標(biāo)量聲明

除了通常的C數(shù)據(jù)類型外,C51編譯器支持“bit”數(shù)據(jù)類型,對(duì)此有下列擴(kuò)充與限制:

(1) 函數(shù)可包含類型為“bit”的參數(shù),也可將其作為返回值。

bit bfunc(bit b0,bit b1){

/*……*/

return(b1);

}

注:使用禁止中斷(#pragma disable)或包含明確的寄存器組切換(using n)的函數(shù)不能返回位值,在這種情況下,編譯器會(huì)識(shí)別出來(lái)并產(chǎn)生一個(gè)錯(cuò)誤信息。

(2) 位標(biāo)量聲明的語(yǔ)法及C聲明的語(yǔ)義

static bit dirction_bit;

extern bit lock_printer_port;

bit display_invers;

(3) 對(duì)于位聲明的限制

l 位不能聲明為一個(gè)指針(bit *bit_poiter)

l 不存在位數(shù)組(bit b_array[5])

位聲明中允許定義存貯器類型,位都被放入一個(gè)位段,它總是在8051內(nèi)部RAM中,因此存貯器類型限制為DATA或IDATA,聲明為其它存貯器類型都將導(dǎo)致編譯出錯(cuò)。

 

1.3.5 可位尋址對(duì)象

可位尋址對(duì)象指可以字節(jié)或位尋址的對(duì)象,當(dāng)對(duì)象位于MSC-51可尋址RAM中時(shí)會(huì)有這種情況,C51允許帶“bdata”類型的對(duì)象放入可位尋址存貯器中。

bdata int ibase; /*位尋址指針 int*/

bdata char bary[4]; /*位尋址數(shù)組 arrray*/

使用“sbit”聲明可獨(dú)立訪問(wèn)可位尋址對(duì)象的位:

sbit mybit0=ibase^0;

sbit mybit15=ibase^15;

sbit ary07=bary[0]^7;

sbit ary37=bary[3]^7;

對(duì)象“ibase”和“bary”也可位尋址:

ary37=0; /*尋址“bary[3]”中的位7*/

ibase=-1; /*尋址字節(jié)地址*/

mybit15=0; /*尋址“ibase”的位15*/

sbit聲明要求基址對(duì)象的存貯器類型為“bdata”,否則只有絕對(duì)的位聲明方法是合法的。位位置(‘^’操作符號(hào)后)的最大值依賴于指定的基類型,這個(gè)值于char/uchar而言是0~7,對(duì)于int/uint/short/ushort而言是0~15,對(duì)于long/ulong而言是0~31。

在編譯器內(nèi)存貯器類型bdata與data一樣操作,并且只作與可再定位的sbit的運(yùn)算。注:可位尋址的的段長(zhǎng)最大不能超過(guò)16字節(jié),可再定位的sbit聲明自動(dòng)轉(zhuǎn)為公共的(PBULIC)以使它們能被其它C模塊使用。

模塊1: sbit ary37=bary[3]^7;

模塊2: extern bit ary37;

sbit聲明也可為結(jié)構(gòu)和函數(shù)所用:

union lft {float mf;long ml;} ;

bdata struct bad { char ml; union lft u; }tcp;

sbit tcpf31=tcp.u.ml^31; /*浮點(diǎn)限制*/

sbit tcpml0=tcp.ml^0;

sbit tcmpl7=tcp.ml.^7;

 

注:位位置的指定不能直接被float類型所用,如果需要這樣做,浮點(diǎn)標(biāo)量必須與一個(gè)長(zhǎng)整型標(biāo)量一起放入一個(gè)聯(lián)合中并且位位置必須由長(zhǎng)整型標(biāo)題指定(見(jiàn)上例)。

1.4 存貯器類型

C51編譯器完全支持8051微處理器及其系列的結(jié)構(gòu),可完全訪問(wèn)MCS-51硬件系統(tǒng)所有部分。每個(gè)變量可準(zhǔn)確地賦予不同的存貯器類型(data,idata,pdata,xdata,code)。訪問(wèn)內(nèi)部數(shù)據(jù)存貯器(idata)要比訪問(wèn)外部數(shù)據(jù)存貯器(xdata)相對(duì)要快一些,因此,可將經(jīng)常使用的變量置于內(nèi)部數(shù)據(jù)存貯器中,而將較大及很少使用的數(shù)據(jù)單元置于外部數(shù)據(jù)存貯器中。

 

 

 

存貯器類型

 

描 述

 

data

 

直接尋址內(nèi)部數(shù)據(jù)存貯器,訪問(wèn)變量速度最快(128bytes)

 

bdata

 

可位尋址內(nèi)部數(shù)據(jù)存貯器,允許位與字節(jié)混合訪問(wèn)(16 bytes)

 

iIdata

 

間接尋址內(nèi)部數(shù)據(jù)存貯器,可訪問(wèn)全部地址空間(256bytes)

 

pPdata

 

分頁(yè)(256bytes)外部數(shù)據(jù)存貯器,由操作碼MOVX @Ri訪問(wèn)

 

xdata

 

外部數(shù)據(jù)存貯器(64K),由MOVX @DPTR訪問(wèn)

 

code

 

代碼數(shù)據(jù)存貯器(64K),由MOVC @A+DPTR訪問(wèn)

 

變量說(shuō)明舉例:

data char charvar;

char code msg[]=”ENTER PARAMETER:”;

unsigned long xdata array[100];

float idata x,y,z;

unsigned char xdata vector[10][4][4];

sfr p0=0x80;

sbit RI="0x98";

char bdata flags;

sbit flago="flags"^0;

如果在變量說(shuō)明時(shí)略去存貯器類型標(biāo)志符,編譯器會(huì)自動(dòng)選擇默認(rèn)的存貯器類型。默認(rèn)的存貯器類型進(jìn)一步由控制指令SMALL、COMPACT和LARGE限制。例如:如果聲明char charvar,則默認(rèn)的存貯器模式為SMALL,charvar放在data存貯器;如果使用COMPACT模式,則charvar放入idata存貯區(qū);在使用LARGE模式的情況下,charvar被放入外部存貯區(qū)或xdata存貯區(qū)。

1.5 存貯器模式

存貯器模式?jīng)Q定了自動(dòng)變量和默認(rèn)存貯器類型,參數(shù)傳遞區(qū)和無(wú)明確存貯區(qū)類型的說(shuō)明。在固定的存貯器地址變量參數(shù)傳遞是C51的一個(gè)標(biāo)準(zhǔn)特征,在SMALL模式下參數(shù)傳遞是在內(nèi)部數(shù)據(jù)存貯區(qū)中完成的。LARGRE和COMPACT模式允許參數(shù)在外部存貯器中傳遞。C51同時(shí)也支持混合模式,例如在LARGE模式下生成的程序可將一些函數(shù)分頁(yè)放入SMALL模式中從而加快執(zhí)行速度。

 

 

 

存貯器模式

 

描 述

 

SMALL

 

參數(shù)及局部變量放入可直接尋址的內(nèi)部寄存器(最大128bytes,默認(rèn)存貯器類型是DATA)

 

COMAPCT

 

參數(shù)及局部變量放入分頁(yè)外內(nèi)部存貯區(qū)(最大256bytes,默認(rèn)存貯器類型是PDATA)

 

LARGE

 

參數(shù)及局部變量直接放入外部數(shù)據(jù)存貯器(最大64K,默認(rèn)存貯器類型是XDATA)

 

 

1.6 指針

Franklin C-51支持“基于存貯器的”和“一般指針”。

 

1.6.1 基于存貯器的指針

基于存貯器的指針由C源代碼中存貯器類型決定并在編譯時(shí)確定,用這種指針可高效訪問(wèn)對(duì)象且只需一個(gè)字節(jié)(idata*,data*,pdata*)或2個(gè)字節(jié)(code*,xdata*)。操作較短指針的代碼被縮短,一般被“內(nèi)行”編碼;庫(kù)調(diào)用不再必要。

聲明舉例:

 

 

char xdata *pt

 

在xdata存貯器中聲明一個(gè)指向?qū)ο箢愋蜑?ldquo;char”的指針。指針默認(rèn)自身在默認(rèn)存貯區(qū)(決定于編譯模式),長(zhǎng)度為2字節(jié)。(值為0~0xFFFF)

 

char xdata *data pdx;

 

除了指針明確位于內(nèi)部數(shù)據(jù)存貯器(data)中外,與上例相同。它與編譯模式無(wú)關(guān)。

 

data char xdata *pdx;

 

本例與上例完全相同。存貯器類型定義既可放在聲明的開(kāi)頭也可直接放在聲明的對(duì)象之前。這種形式是為了與早期C-51編譯器版本兼容。

 

上面例子闡明了指針的一般聲明及使用。它們與所有的數(shù)據(jù)類型和存貯器類型相關(guān)。所有用于一般指針的操作同樣可用于基于存貯器的指針。

 

1.6.2 一般指針

“一般”指針需3個(gè)字節(jié):1個(gè)字節(jié)為存貯類型,2個(gè)字節(jié)為偏移量。存貯器類型決定了對(duì)象所用的8051存貯器空間,偏移量指向?qū)嶋H地址。一個(gè)“一般”指針可訪問(wèn)任何變量而不管它在8051存貯器空間中的位置。這樣就允許一般性函數(shù),如memcpy將數(shù)據(jù)從任意一個(gè)地址拷貝到另一個(gè)地址空間。

 

1.6.3 基于存貯器的指針與一般指針的轉(zhuǎn)換

一個(gè)已定位指針可轉(zhuǎn)換為一個(gè)一般指針(3字節(jié))及副本。這在某些時(shí)候是很有用的。例如庫(kù)函數(shù)包含一個(gè)一般指針變量,象printf(),sprintf(),gets()等包含一個(gè)一般指針變量,如同以前的編譯器和庫(kù)版本一樣。這些函數(shù)因而廣泛適用。

例:extern int printf(void *format,…);

在printf調(diào)用中,2字節(jié)指針自動(dòng)轉(zhuǎn)換為一個(gè)3字節(jié)指針,而printf的原型正需要一個(gè)一般指針(3字節(jié))作為其第一參量。

注:如果沒(méi)有函數(shù)原型,函數(shù)調(diào)用的參量中指針總是轉(zhuǎn)換為一般指針。如果函數(shù)確實(shí)需要一個(gè)短指針作參量,這會(huì)產(chǎn)生錯(cuò)誤,為了避免在程序中發(fā)生這類錯(cuò)誤,需要使用頭文件,或某些函數(shù)聲明函數(shù)原型。這將保證讓編譯器轉(zhuǎn)換為所需類型,否則會(huì)產(chǎn)生類型不匹配錯(cuò)誤。

例:指針定義說(shuō)明

 

 

指 針 說(shuō) 明

 

長(zhǎng) 度

 

指 向

 

float *p;

 

3 字節(jié)

 

所有8051存貯器空間中的“float”(一般指針)

 

char data *dp;

 

1字節(jié)

 

“data”存貯器中的“char”

 

int idata *ip;

 

1字節(jié)

 

“idata”中的“int”

 

long pdata *pp;

 

1字節(jié)

 

“pdata”中的“long”

 

char xdata *xp;

 

2字節(jié)

 

“xdata”中的“char”

 

int code *cp;

 

2字節(jié)

 

“code”中的“int”

 

 

1.6.4 抽象指針類型

抽象指針類型用來(lái)在每個(gè)存貯區(qū)訪問(wèn)任意絕對(duì)地址,或來(lái)產(chǎn)生絕對(duì)CALLs。在這個(gè)過(guò)程中,常數(shù)類型或字符型、整型都用抽象類型作了原則性修改(類型整理)以允許進(jìn)行絕對(duì)訪問(wèn)或調(diào)用。

例:

char xdata *px;

char idata *pi;

char code *pc;

char c;

int i;

pc = (void*)main;

i = ((int(code*)(void))0xFF00(); /*LCALL 0FF00H */

c = *((char code*)0x8000); /*char [code[0x8000]]*/

i = *((int code*)0x1200); /*int from code[0x1200]*/

px = *((char xdata *xdata*)0x4000); /*x ptr from xdata[0x4000]*/

px = ((char xdata *xdata*)0x4000)[0]; /*同上*/

px = ((char xdata *xdata *)0x4000)[1] /*x ptr from xdata[0x4002]*/

1.7 寄存器組定義

8051系列的器件包含4個(gè)相同的寄存器組,每個(gè)寄存器組包括8個(gè)寄存器(R0~R7),C51編譯器可使在一函數(shù)中決定用哪一寄存器組成為可能。絕對(duì)寄存器的訪問(wèn)可用AREGS/NOAREGS和REGISTERBANK來(lái)控制。

定義一個(gè)帶擴(kuò)展性的函數(shù)語(yǔ)法如下:

返回類型 函數(shù)名([參數(shù)])[模式][再入][中斷 n]using n

再入和中斷將在后兩節(jié)討論。

例:void rb_function(void) using 3;

“using”不允許用于外部函數(shù),它對(duì)函數(shù)的目標(biāo)代碼影響如下:

l 函數(shù)入口處將當(dāng)前寄存器保存入棧;

l 指它的寄存器還會(huì)改變;

l 函數(shù)退出前寄存器組被恢復(fù)。

“using”定義對(duì)于返回一個(gè)寄存器內(nèi)的值的函數(shù)是無(wú)用的。編程者必須十分小心以保證任何寄存器切換都只在仔細(xì)控制的區(qū)域發(fā)生。如果不做到這一點(diǎn)將會(huì)產(chǎn)生不正確的函數(shù)結(jié)果。即使當(dāng)編程者使用同一寄存器組時(shí),帶“using”屬性的函數(shù)原則上也不能返回一個(gè)位值。

實(shí)際產(chǎn)生的代碼決定于編譯器及不同開(kāi)關(guān)條件,有時(shí)用命令產(chǎn)生絕對(duì)的寄存器地址,當(dāng)需要進(jìn)行這樣的地址計(jì)算時(shí),使用REGISTERBANK指令的影響只是計(jì)算Arn寄存器使用的地址,而必進(jìn)行實(shí)際切換。

1.8 中斷服務(wù)程序

C51編譯器及其對(duì)C語(yǔ)言的擴(kuò)充允許編程者對(duì)中斷的所有方面進(jìn)行控制。這種支持能使系統(tǒng)編程者創(chuàng)建高效的中斷服務(wù)程序,用戶只需在普通和高級(jí)方式下關(guān)心中斷及必要的寄存器組切換操作,C51編譯器將產(chǎn)生最合適的代碼。

 

1.8.1 中斷服務(wù)程序的定義

使用中斷服務(wù)函數(shù)的完整語(yǔ)法如下:

返回值 函數(shù)名([參數(shù)])[模式][再入] interrupt n[using n]

“interrupt”后接一個(gè)0~31的常數(shù),不允許使用表達(dá)式。

中斷不允許用于外部函數(shù),它對(duì)函數(shù)目標(biāo)代碼的影響如下:

l 當(dāng)使用函數(shù)時(shí),SFR中的ACC、B、DPH、DPL和PSW(當(dāng)需要時(shí))入棧;

l 如不使用寄存器組切換,甚至中斷函數(shù)所需的所有工作寄存器(Rn)都入棧;

l 函數(shù)退出前,所有的寄存器內(nèi)容出棧;

l 函數(shù)由8051控制命令“RETI”終止。

 

1.8.2 開(kāi)發(fā)中斷過(guò)程時(shí)的規(guī)則

l 不能進(jìn)行參數(shù)傳遞,如果中斷過(guò)程包括任何參數(shù)聲明,編譯器將產(chǎn)生一個(gè)錯(cuò)誤信息;

l 無(wú)返回值,如果想定義一個(gè)返回值將產(chǎn)生錯(cuò)誤,然而,如果返回整型值編譯器將不產(chǎn)生錯(cuò)誤信息,因?yàn)檎椭凳悄J(rèn)值,因而編譯器不能清楚識(shí)別。

l 編譯器會(huì)識(shí)別對(duì)中斷過(guò)程的直接調(diào)用并拒絕它們,在任何情況下不能直接調(diào)用中斷過(guò)程,因?yàn)橥顺鲈撨^(guò)程是由操作碼RETI完成的。RETI影響8051芯片的硬件中斷系統(tǒng),由于硬件上沒(méi)有中斷請(qǐng)求存在,因而這個(gè)操作碼的結(jié)果是不定的并且通常是致命的。由于疏忽,可能用指針來(lái)間接調(diào)用它,這是值得注意的。

l 編譯器從絕對(duì)地址8n+3處產(chǎn)生一個(gè)中斷向量,其中n為中斷號(hào),該向量包括一個(gè)到中斷過(guò)程的跳轉(zhuǎn),向量的產(chǎn)生可由指令NOINTVECTOR壓縮。因而用戶有能力從獨(dú)立的匯編模塊中提供中斷向量。

l C51編譯器允許0~31個(gè)中斷,究竟允許哪些中斷依賴于使用的8051系列芯片,編譯器不能檢查。

l 如果中斷程序中有浮點(diǎn)運(yùn)算,必須保持浮點(diǎn)寄存器狀態(tài),當(dāng)沒(méi)有其它程序執(zhí)行浮點(diǎn)運(yùn)算時(shí),可能不保存,函數(shù)“fsave”和“fprestore”用來(lái)保存浮點(diǎn)狀態(tài)。

l 中斷過(guò)程調(diào)用的函數(shù)所使用的寄存器必須與中斷過(guò)程相同,當(dāng)沒(méi)有使用“using”指令時(shí),編譯器會(huì)選擇一個(gè)寄存器組作絕對(duì)寄存器訪問(wèn),當(dāng)子程序使用另一個(gè)寄存器組時(shí)會(huì)發(fā)生錯(cuò)誤,用戶必須保證按要求使用相應(yīng)寄存器組,C編譯器不會(huì)對(duì)此檢查。

例:

unsigned int interruptent;

unsigned char second;

time() interrupt 1 using 2 /*定時(shí)器0中斷服務(wù)程序,工作寄存器使用2區(qū)*/

{

if(++interruptcnt==4000) {

second++; /*秒計(jì)數(shù)加一*/

interruptcnt=0; /*清中斷計(jì)數(shù)*/

}

}

1.9 再入函數(shù)

再入函數(shù)可被遞歸調(diào)用,調(diào)用可發(fā)生在任何時(shí)候,即使是在中斷過(guò)程中。在實(shí)時(shí)處理的應(yīng)用問(wèn)題中常常需要再入函數(shù)。

使用關(guān)鍵字“reentrant”可有選擇地定義函數(shù)有再入能力。在存貯器模式的基礎(chǔ)上為再入函數(shù)在內(nèi)部或外部存貯器中模擬了一個(gè)棧區(qū)域。由于MCS-51缺乏合適的尋址方法,使用棧結(jié)構(gòu)是相當(dāng)必要的。因而應(yīng)盡量少用再入函數(shù)。

定義一再入函數(shù)的語(yǔ)法如下:

返回值 函數(shù)名([參數(shù)])[模式]reetrant[interrupt n][using n]

例:

int calc(char i,int b) reentrant {

int x;

x=table[i];

return(x*b);

}

使用再入函數(shù)有如下規(guī)定:

l 不能傳遞類型為“bit”的參數(shù)。也不能聲明一個(gè)局部標(biāo)量,再入功能不能包括位操作及MCS-51可位尋址區(qū)域。

l 不能在“alien”函數(shù)調(diào)用再入函數(shù)。

l 再入函數(shù)可同時(shí)有其它屬性,如“using”函數(shù)模式和“interrupt”。

l 再入函數(shù)不能同時(shí)有“alien”屬性,從而遵守PL/M規(guī)則。

l 返回地址及可能的PUSH/POP操作存入MCS-51的棧中或被執(zhí)行(不在再入棧中)。

l 在同一模塊中,任意模塊的再入函數(shù)(small reentrant,lage reentrant,compact reentrant)不能與具有不同模式的再入函數(shù)混合。

再入函數(shù)舉例:

/*這個(gè)再入函數(shù)可以從“main”及中斷程序中調(diào)用*/

int calc(char i,int b)reentrant {

int x;

x=table[i];

return(x*b);

}

1.10 參數(shù)傳遞

通過(guò)CPU的寄存器可傳遞至多三個(gè)參數(shù)。這樣產(chǎn)生與匯編子程序相當(dāng)?shù)挠行?shù)機(jī)制。如果寄存器被占用,或說(shuō)明了“#pragma NOREGPARMS”,參數(shù)變量將使用固定的存貯器位置,存貯器模式?jīng)Q定了8051存貯器為參數(shù)提供的位置。

表:候選的參數(shù)寄存器

 

 

參數(shù)類型

 

char,1字節(jié)指針

 

int,2字節(jié)指針

 

long,float

 

一般指針

 

一個(gè)參數(shù)

 

R7

 

R6,R7

 

R4~R7

 

R1,R2,R3

 

二個(gè)參數(shù)

 

R5

 

R4,R5

 

R4~R7

 

R1,R2,R3

 

三個(gè)參數(shù)

 

R3

 

R2,R3

 

 

R1,R2,R3

 

 

函數(shù)的返回值放在CPU固定的寄存器中,列表如下。這樣,與匯編子程序的接口變得非常容易。

 

表:函數(shù)返回值的寄存器用法

 

 

返 回 值

 

寄 存 器

 

意 義

 

bit

 

進(jìn)位標(biāo)志 C

 

 

 

(unsigned) char

 

R7

 

 

 

(unsigned) int

 

R6,R7

 

高位在R6,低位在R7

 

(unsigned) long

 

R4~R7

 

高位在R4,低位在R7

 

float

 

R4~R7

 

32位IEEE格式

 

指 針

 

R1,R2,R3

 

類型選擇在R3,高位在R2,低位在R1

 

 

1.11 PL/M51接口

Franklin C51利用關(guān)鍵字“alien”提供了一個(gè)與Intel PL/M-51直接和簡(jiǎn)單和接口,關(guān)鍵字“alien”在所有存貯器模式下可用于“extern”和“public”函數(shù)。現(xiàn)有的PL/M-51程序利用C語(yǔ)言的強(qiáng)大功能可與Franklin C-51連接起來(lái)。

使用關(guān)鍵字“alien”,C51可用PL/M-51規(guī)定的參數(shù)傳遞方式工作。“alien”可用于外部或公共函數(shù),并可用于任一模式,這樣,已有的PL/M-51程序可加入到C-51中。Alien函數(shù)始終包含一個(gè)標(biāo)準(zhǔn)的參數(shù)數(shù)量,因此,C中定義的三點(diǎn)(…)記號(hào)不被接受,且會(huì)產(chǎn)生一個(gè)錯(cuò)誤信息。

例:

extern alien char plm_function(unsigned char,unsigned int);

extern char c_function(unsigned char x,unsigned char y) {

return(x*y);

}

PL/M-51兼容函數(shù)必須定義以關(guān)鍵字“alien”。這樣,PL/M函數(shù)的參數(shù)傳遞及參數(shù)返回規(guī)定在C編譯器中才被考慮。

1.12 匯編接口

參數(shù)是通過(guò)固定的CPU寄存器傳給匯編程序的,當(dāng)使用“#pragma NOREGPARMS”時(shí),則通過(guò)固定的存貯器位置傳遞參數(shù)。這樣就給匯編與Franklin C-51之間提供了一個(gè)非常簡(jiǎn)潔的接口。返回值在CPU寄存器中。

下例為在匯編中用來(lái)編碼的“toupper”函數(shù),參數(shù)傳遞發(fā)生在寄存器中。

UPPER SEGMENT CODE ;程序代碼段

PUBLIC _toupper ;入口地址

RESG UPPER ;選擇程序代碼段

toupper: MOV A,R7 ;char 參數(shù)在寄存器R7中

CJNE A,#’a’,UPP1

UPP1: JC UPPERT

CJNE A,#’z’+1,UPP2

UPP2: JNE UPPRET

CLR ACC.5

UPPRET: MOV R7,A ;char 返回值在寄存器R7中

RET ;返回C

1.13 內(nèi)部函數(shù)

Franklin C-51支持下列內(nèi)部函數(shù)。內(nèi)部函數(shù)既是再入的又是有效的。

表:C51的內(nèi)部函數(shù)

 

 

函 數(shù)

 

描 述

 

memcpy,memsset,memchr,memmove,memcmp

 

ANSI的內(nèi)存操作功能

 

strcmp,strcpy

 

ANSI字符串處理功能

 

_crol_,_irol_,lrol_

 

左移字符、整數(shù)、長(zhǎng)整數(shù)

 

_crolr_,_irolr_,lrolr_

 

右移字符、整數(shù)、長(zhǎng)整數(shù)

 

_nop_

 

空操作

 

_testbit_

 

測(cè)試并清位(JBC指令)

 

 

1.14 代碼優(yōu)化

Franklin C51可將即使有經(jīng)驗(yàn)的程序員編制的代碼進(jìn)行優(yōu)化。用戶可選6個(gè)優(yōu)化級(jí),另外,用OPTIMIZE(SIZE),NOREGPARMS和NOAREGS時(shí)會(huì)影響生成代碼的類型。C51的所有優(yōu)化如下:

(1) 一般優(yōu)化:

l 常數(shù)折迭:發(fā)生在一個(gè)表達(dá)式或地址計(jì)算中的幾個(gè)常數(shù)值組合為一個(gè)常數(shù)。

l 跳轉(zhuǎn)優(yōu)化:跳轉(zhuǎn)轉(zhuǎn)到最終的目標(biāo)地址,以提高程序效率。

l 死碼消除:不可執(zhí)行代碼(死碼)可從程序中去掉。

l 寄存器變量:只要有可能,自動(dòng)變量和參量放入寄存器中,為這些變量保留的數(shù)據(jù)存貯器將去除。

l 通過(guò)寄存器傳遞參數(shù):寄存器中可傳遞最多三個(gè)參數(shù)。

l 全局公共子式消除:相同的子表達(dá)式或地址計(jì)算(多次發(fā)生在同一函數(shù)中)將被識(shí)別出來(lái),并且只要有可能,將只計(jì)算一次。

(2) 基于8051的優(yōu)化:

l 窺孔(PEEPHOLE)優(yōu)化:只要能節(jié)省存貯空間或執(zhí)行時(shí)間,復(fù)雜的運(yùn)算都將化簡(jiǎn)。

l 訪問(wèn)優(yōu)化:常數(shù)和變量直接包含在操作中。

l 數(shù)據(jù)覆蓋:函數(shù)的數(shù)據(jù)和位移被標(biāo)記為OVERLAYABLE,被L51用其它數(shù)據(jù)和位覆蓋。

l CASE/SWITCH優(yōu)化:SWITCH/CASE語(yǔ)句優(yōu)化為一個(gè)跳轉(zhuǎn)或一串跳轉(zhuǎn)。

(3) 代碼生成選項(xiàng):

l OPTMIZE(SIZE):共同的“C”操作被子程序代替:程序碼長(zhǎng)被壓縮。

l NOAREGS:不使用絕對(duì)寄存器訪問(wèn),程序代碼在這種方式下獨(dú)立于寄存器組。

l NOREGPARMS:參數(shù)傳遞總是在本數(shù)據(jù)段完成,程序代碼與早期C-51版本兼容。

1.15 C庫(kù)

C-51編譯器包含6個(gè)不同的編譯庫(kù),可根據(jù)不同函數(shù)的需要進(jìn)行優(yōu)化,這些庫(kù)幾乎支持所有的ANSI函數(shù)調(diào)用。因此,用此標(biāo)準(zhǔn)的C程序可在編譯和連接后立即運(yùn)行。

 

 

庫(kù)

 

描 述

 

C51S.LIB

 

SMALL模式,無(wú)浮點(diǎn)運(yùn)算

 

C51FPS.LIB

 

浮點(diǎn)數(shù)學(xué)運(yùn)算庫(kù)(SMALL模式)

 

C51C.LIB

 

COMPACT模式,無(wú)浮點(diǎn)運(yùn)算

 

C51FPC.LIB

 

浮點(diǎn)運(yùn)算庫(kù)(COMPACT模式)

 

C51L.LIB

 

LARGE模式,無(wú)浮點(diǎn)運(yùn)算

 

C51FPL.LIB

 

浮點(diǎn)運(yùn)算庫(kù)(LARGE模式)

 

C51編譯器包含的庫(kù)模塊,都有源代碼,對(duì)它們可作與硬件相關(guān)的修改。用戶改變對(duì)于現(xiàn)有硬件輸入和輸出結(jié)構(gòu)的兩個(gè)模塊,就可修改所有庫(kù)函數(shù),同樣也可以重新很快地構(gòu)造如“printf”和“puts”函數(shù)用LCD顯示。

L51連接器的檢查從而保證所有模塊都用一種模式編譯并自動(dòng)選擇編譯庫(kù),從而使用戶完全可以不用不同庫(kù)的細(xì)節(jié)。

1.16 配置文件

C51編譯器可根據(jù)不同的硬件環(huán)境由4個(gè)文件作出修改。下列配置文件包括在C-51軟件包中:

 

 

STARTUP51.51:

 

 

C51編譯器的啟動(dòng)程序,所有的棧指針和存貯器,只要需要,將被初始化。

 

INIT.A51:

 

 

在文件中已明確初始化了變量作初始化。如果系統(tǒng)裝入“看門狗”,該文件可包含附加的“看門狗”刷新。

 

PUBCHAR.C:

 

函數(shù)“printf”、“puts”等的字符輸出核心程序,該程序可根據(jù)用戶硬件加以修改(如LCD顯示)。

 

GETKEY.C:

 

函數(shù)“getchar”、“scanf”等的字符輸入核心程序,該程序可根據(jù)硬件加以修改(如矩陣鍵盤)。

 

所有的文件都包含在C運(yùn)行庫(kù)中,因此,不能在連接時(shí)指定調(diào)用。如果用戶改變一個(gè)文件,可將其編譯后與其它目標(biāo)文件一起連接,因而不必改動(dòng)運(yùn)行庫(kù)。庫(kù)中原文件自動(dòng)忽略。

例:

L51 DEMO1.OBJ,DEMO2.OBJ,STARTUP.OBJ,PUTCHAR.OBJ

本例將用戶建立的STARTUP.OBJ和PUTCHAR.OBJ連接起來(lái)

 

STARTUP.A51

文件STARTUP.51開(kāi)頭包含一些C編譯結(jié)構(gòu)使用的EQU語(yǔ)句。每個(gè)EQU語(yǔ)句的功能描述如下:

IDATALEN 聲明系統(tǒng)開(kāi)始時(shí)有多少內(nèi)存需要用0初始化。默認(rèn)值為80H,因?yàn)閹缀趺總€(gè)

8051指令至少包含128字節(jié)內(nèi)部RAM。對(duì)于256字節(jié)內(nèi)部RAM的8052可使用100H。當(dāng)用戶程序在開(kāi)始時(shí)需要使用0初始化的內(nèi)存時(shí)才有必要作改動(dòng)。如果內(nèi)存初始化必須保持對(duì)掉電模式系統(tǒng)的完全抑制,IDATALEN應(yīng)設(shè)為0。這種情況下至少得保持所有位于段?C_LIB_DATA和?C_LIB_DBIT中的變量都置為0。否則有些庫(kù)函數(shù)不能完全發(fā)揮作用,?C_LIB_DATA段的長(zhǎng)度因不同應(yīng)用問(wèn)題而不同,其當(dāng)前長(zhǎng)度可在MAP文件中找到。

XDATASTART

XDATALEN 表明了需要以0初始化的PDATA區(qū)首址和長(zhǎng)度,XDATASTART指明了XDATA區(qū)首址,XDATALEN表明了需初始化的字節(jié)數(shù)。

PDATASTART

PDATALEN 表明了需以0初始化的PDATA區(qū)首址及長(zhǎng)度,PDATASTART指明了首址,XDATALEN指定了長(zhǎng)度。

LBPSTACK

LBPSTACKTOP 定義了SMALL模式下創(chuàng)建的再入函數(shù)使用的棧區(qū)。LBPSTACK表明是否對(duì)棧指針(變量?C_LBP)初始化,LBPSTACKTOP指明了棧頂首址。對(duì)于具有256字節(jié)內(nèi)部RAM的8051系統(tǒng),當(dāng)存貯區(qū)作首址為0XFF的棧時(shí),可不初始化。C51不作棧區(qū)是否滿足特定應(yīng)用的檢查,用戶必須自己進(jìn)行測(cè)試。

XBPSTACK

XBPSTACKTOP 為在LARGE模式下創(chuàng)建的再入函數(shù)定義了棧區(qū),XBPSTACK表明指針(變量?C_XBP)是否初始化,XBPSTACKTOP指定了棧頂?shù)刂贰.?dāng)存貯區(qū)作為首址為0Xffff(在XDATA區(qū))的棧時(shí),可不作初始化。同上一樣,C51不作棧檢查,需要用戶自己測(cè)試。

PBPSTACK

PBPSTACKTOP 為在COMPACT模式下創(chuàng)建的再入函數(shù)定義了棧區(qū),PBPSTACK表明棧指針(變量?C_PBP)是否初始化。PBPSTACKTOP指定了棧頂?shù)刂?。?dāng)存貯區(qū)作為首址為0Xff(在PDATA區(qū))的棧時(shí),可不作初始化。同上一樣,C51不作棧檢查,需要用戶自己測(cè)試。

PPAGEENABLE

PPAGE 當(dāng)在COMPACT模式中用16位尋址XDATA存貯區(qū)時(shí)需要這些指令。對(duì)于使用LARGE模式的程序,可用它提高運(yùn)行速度或減小代碼長(zhǎng)度。PPAGEENABLE允許8051端口2的初始化,對(duì)端口2的尋址允許在任意XDATA頁(yè)256字節(jié)變量空間的映射。這兩個(gè)指令必須和L51的控制指令PDATA一起使用。PDATA指定了XDATA存貯器中PDATA區(qū)的首址。例:在STARTUP.A51中,PPAGEENABLE置為1,PPAGE置為10H。這種情況下PDATA區(qū)首址為1000H(10H頁(yè)),而L51必須包含一個(gè)值在1000和10FFH之間的控制語(yǔ)句:L51〈輸入模塊〉PDATA(1050H)。注:L51和C51都不對(duì)PPAGE/PDATA指令正確性進(jìn)行檢查,用戶必須保證PPAGE和PDATA包含一個(gè)合適的值。

INIT.A51:

文件INIT.A51包含一個(gè)定義了“看門狗”刷新的宏。當(dāng)系統(tǒng)包括“看門狗”以及用戶變量初始化時(shí)間比“看門狗”刷新時(shí)間要長(zhǎng)時(shí),必須改變這個(gè)宏。這種情況下,宏WATCHCOG必須包含“看門狗”刷新的代碼。

例: ;Watchdog refresh for 80515 system

WATCHDOG MACRO

SETB WDT

SETB SWDT

ENDM

PUTCHAR.C

文件PUTCHAR.C包含字符輸出的核心程序,該文件通過(guò)串行口輸出。這種情況下考慮了XON/XOFF協(xié)議,字符LF()被轉(zhuǎn)為字符串CR,LF,這在很多終端中是需要的。用戶可按自己的要求改變putchar()函數(shù)。

GETKEY.C

文件GETKEY.C包含字符輸入的核心程序,該文件從串行接口讀入一個(gè)字符,不作數(shù)據(jù)轉(zhuǎn)換,用戶可根據(jù)需要修改getkey()函數(shù)。

 

本節(jié)包含幾個(gè)怎樣提高8051程序效率的注解。

 

定位變量

經(jīng)常訪問(wèn)的數(shù)據(jù)對(duì)象應(yīng)放入在片內(nèi)數(shù)據(jù)RAM中,這可在任一模式(COMPACT/LARGE)下用輸入存貯器類型的方法實(shí)現(xiàn)。訪問(wèn)片內(nèi)數(shù)據(jù)RAM要比訪問(wèn)外部數(shù)據(jù)存貯器快得多。片內(nèi)RAM由寄存器組,位數(shù)據(jù)區(qū)棧和其它由用戶用“data”類型定義的變量共享。由于片內(nèi)RAM容量的限制(128~256字節(jié),由使用的處理器決定),必須權(quán)衡利弊以解決訪問(wèn)效率和這些對(duì)象的數(shù)量之間的矛盾。

 

總是使用可能的最小數(shù)據(jù)類型

8051系列CPU都是8位機(jī),因此,顯然對(duì)具有“char”類型的對(duì)象的操作比“int”或“long”類型的對(duì)象方便得多。建議編程者只要滿足要求,應(yīng)盡量使用最小數(shù)據(jù)類型。

C51編譯器直接支持所有的字節(jié)操作,因而如果不是運(yùn)算符要求,就不作“int”類型的轉(zhuǎn)換,這可用一個(gè)乘積運(yùn)算來(lái)清楚說(shuō)明,兩個(gè)“char類型”對(duì)象的乘積與8051操作碼“MUL AB”剛好相符。如果用整型量完成同樣的運(yùn)算,則需要調(diào)用庫(kù)函數(shù)。

 

只要有可能,使用“unsigned”數(shù)據(jù)類型

8051系列CPU并不直接支持有符號(hào)數(shù)的運(yùn)算。因而C51編譯器必須產(chǎn)生與之相關(guān)的更多的代碼以解決這個(gè)問(wèn)題。如果使用無(wú)符號(hào)類型,產(chǎn)生的代碼要少得多。

 

只要有可能,使用局部函數(shù)變量

編譯器總是嘗試在寄存器里保持局中變量。這樣,將索引變量(如FOR和WHILE循環(huán)中計(jì)數(shù)變量)聲明為局部變量是最好的,這個(gè)優(yōu)化步驟只為局部變量執(zhí)行。使用“unsigned char/int”的對(duì)象通常能獲得最好的結(jié)果。

 

2 C51編譯器控制指令

 

編譯選項(xiàng)可能被控制指令激活、禁止或改變。這些指令可在命令行輸入或在源文件上加入#pragma給預(yù)處理器??刂浦噶罘譃閮山M,即首要的和一般的,并可分為三類:源控制、目標(biāo)控制、列表控制。見(jiàn)表2.1編譯控制指令。“P/G”列表明指令是首要的或是一般的,首要指令僅出現(xiàn)一次,一般指令按需要可出現(xiàn)多次。

 

表2.1 編譯控制指令

 

 

分 類

 

P/G

 

 

指 令

 

縮 寫

 

默 認(rèn) 值

 

 

P

G

G

G

P

 

DEFINE

SAVE

RESTORE

DISABLE

[NO]EXTEND

 

DF

——

 

EXTEND

 

目 標(biāo)

 

P

P

P

P

P

P

G

G

G

P

P

P

 

[NO]DEBUG

[NO]OBJECT

OPTIMIZE(n)

SMALL

COMPACT

LARGE

[NO]REGPARMS

REGISTERBANK(n)

[NO]AREGS

[NO]INTVECTER

OBJECTEXTEND

ROM()

 

[NO]DB

[NO]OJ

OT

SM

CP

LA

[NO]RP

RB

[NO]AR

[NO]IV

OE

 

NODEBUG

OBJECT(名字.OBJ)

OPTIMIZE(2)

SMALL

REGPARMS

REGISTERBANK(0)

AREGS

INTVECTOR

ROM(LARGE)

 

列 表

 

P

P

P

P

P

P

P

G

P

 

[NO]LISTINCLUDE

[NO]SYMBOLS

[NO]PREPRINT

[NO]CODE

[NO]PRINT

[NO]CODE

PAGELENGTH(n)

EJECT

PAGEWIDTH(n)

 

[NO]LC

[NO]SB

[NO]PP

[NO]CD

[NO]PR

[NO]CO

PL

EJ

PW

 

NOLISTINCLUDE

NOSYMBOLS

NOPREPRINT

NOCODE

PRINT(名字.OBJ)

CODE

PAGELENGTH(69)

PAGEWIDTH(132)

 

2.1 源控制

2.1.1 DEFINE

名 字: DEFINE

縮 寫: DF

變 量: 一個(gè)或幾個(gè)由逗號(hào)分開(kāi)的名字,與C語(yǔ)言的命令規(guī)格一致。

默認(rèn)值: 無(wú)

DEFINE 指令定義了在命令行使用的名字,可為“if”,“ifdef”及“ifndef”等預(yù)處理命令作條件編譯,定義的名字被精確拷貝,因而對(duì)大小寫敏感。

例: C51 DEMO.C DEFINE(check,NoExtRam)

 

2.1.2 SAVE/RESTORE

名 字: SAVE/RESTORE

縮 寫: 無(wú)

變 量: 無(wú)

默認(rèn)值: 無(wú)

SAVE指令存儲(chǔ)當(dāng)前的ARGES,REGPARMS,OPTIMIZE因子和優(yōu)化選項(xiàng)的SPEEDSIZE設(shè)置。這樣,上面所述的設(shè)置被保留下來(lái),例如在#INCLUDE語(yǔ)句之前用SAVE保護(hù),然后用RESTORE指令恢復(fù)。

SAVE/RESTORE只能在源文件中以#pragma語(yǔ)句的參數(shù)形式出現(xiàn),而不能用于命令行。

例:

#pragma save

#pragma noregparms

extern void test1(char c,int I);

extern char test2(long l,float f);

#pragma restore

兩個(gè)外部函數(shù)的寄存器內(nèi)參數(shù)傳遞被禁止,然后SAVE指令時(shí)的設(shè)置被恢復(fù)。

 

2.1.3 DISABLE

名 字: DISABLE

縮 寫: 無(wú)

變 量: 無(wú)

默認(rèn)值:無(wú)

DISABLE指令在一個(gè)函數(shù)執(zhí)行期間禁止中斷發(fā)生。DISABLE必須在函數(shù)前以#pragma指定并且只能用在一個(gè)函數(shù)中,因此它是由編譯器內(nèi)部設(shè)置的,每個(gè)要禁止的中斷在函數(shù)前必須包括一個(gè)獨(dú)立的#pragma指定,而不能用于命令行。

例: typedef using char uchar;

#pragma disable /*Disable interrupts */

uchar dfunc(uchar p1,uchar p2) {

return(p1*P2+P2*p1);

}

 

2.1.4 EXTEND/NOEXTEND

名 字: EXTEND/NOEXTEND

縮 寫: 無(wú)

變 量: 無(wú)

默認(rèn)值: EXTEND

EXTEND指令支持ANSI-C對(duì)C51的特殊擴(kuò)展。NOEXTEND指令使編譯器只處理ANSI-C。不同的保留字如bit,reentrant,using等對(duì)編譯器來(lái)說(shuō)是未知的。

例: C51 DEMO.C NOEXTEND

#pragma NOEXTEND

2.2 目標(biāo)控制

2.2.1 DEBUG/NODEBUG

名 字: DEBUG/NODEBUG

縮 寫: DB/NODB

變 量: 無(wú)

默認(rèn)值:NODEBUG

DEBUG指令指示編譯器將調(diào)試信息加入到目標(biāo)文件中,該信息對(duì)于符號(hào)調(diào)試而言是必需的,它包括全局和局部變量的定義及其地址、以及函數(shù)名及其行號(hào)。目標(biāo)模塊中的調(diào)試信息在用L51連接過(guò)程中一直保持有效,它也可被與dscope-51或intel兼容的仿真器使用。NODEBUG指令指示在目標(biāo)文件中不加入調(diào)試信息。QTH建議用戶要加入DB信息。

例: C51 DEMO.C DEBUG

#pragma db

 

2.2.2 OBJECT/NOOBJECT

名 字: OBJECT/NOOBJECT

縮 寫: OJ/NOOJ

變 量: 括號(hào)內(nèi)文件名

默認(rèn)值: OBJECT(bname.OBJ)

OBJECT(filename)指令改變生成的目標(biāo)文件名,默認(rèn)值是路徑名加上基本擴(kuò)展名“.OBJ”,NOOBJECT指令不產(chǎn)生目標(biāo)文件。

例: C51 DEMO.C NOOBJEECT

#pragma oj(demo.obj)

 

2.2.3 OBJECTEXTEND

名 字: OBJECTEXTEND

縮 寫: OE

變 量: 無(wú)

默認(rèn)值: 無(wú)

OBJECTEXTEND使編譯器產(chǎn)生的目標(biāo)文件包含附加的變量類型定義信息。這個(gè)信息可在目標(biāo)模塊具有相同名字的時(shí)候?qū)⑺鼈儏^(qū)別開(kāi)來(lái)以供不同的仿真器使用。

注:QTH系列仿真器不需要該控制項(xiàng)。

 

2.2.4 OPTIMIZE

名 字: OPTIMIZE

縮 寫: OT

變 量: 括號(hào)內(nèi)一個(gè)0~5的十進(jìn)制數(shù),另外可選OPTIMIZE(SIZE)和OPTIMIZE(SPEED)

以決定優(yōu)化重點(diǎn)是放在代碼長(zhǎng)度上還是執(zhí)行速度上。

默認(rèn)值:OPTIMIZE(2,SPEED)。

OPTIMIZE指令設(shè)置優(yōu)化級(jí),在這種設(shè)置中,高一級(jí)的優(yōu)化級(jí)包含前一級(jí)較低的優(yōu)化級(jí)的設(shè)置。

(1) OPTIMIZE(0)

l 常數(shù)折疊:編譯時(shí)只要有可能,編譯器就執(zhí)行包含常數(shù)的計(jì)算,包括執(zhí)行地址計(jì)算。

l 簡(jiǎn)單訪問(wèn)化:對(duì)8051系統(tǒng)內(nèi)部數(shù)據(jù)和地址進(jìn)行訪問(wèn)優(yōu)化。

l 跳轉(zhuǎn)優(yōu)化:編譯器總是將跳轉(zhuǎn)延遲至最終目標(biāo)上,因此跳轉(zhuǎn)到跳轉(zhuǎn)的指令被消除。

(2) OPTIMIZE(1)

l 死碼消除:無(wú)用的代碼將被消除。

l 跳轉(zhuǎn)否決:根據(jù)一個(gè)測(cè)試反饋,條件轉(zhuǎn)移被仔細(xì)檢查,以決定是否能夠進(jìn)行簡(jiǎn)化或消除。

(3) OPTIMIZE(2)

l 數(shù)據(jù)覆蓋:適用于靜態(tài)覆蓋的數(shù)據(jù)和位段被鑒別并標(biāo)記出來(lái)。L51有這樣一個(gè)功能,通過(guò)對(duì)全局?jǐn)?shù)據(jù)流的分析,選擇可靜態(tài)覆蓋的段。

(4) OPTIMIZE(3)

l “窺孔”優(yōu)化:冗余的MOV指令被刪去,這也包括不必要的、從存貯器裝入對(duì)象及裝入常數(shù)的操作。另外,當(dāng)它能節(jié)省存貯器空間或執(zhí)行時(shí)間時(shí),復(fù)雜操作由簡(jiǎn)單操作所取代。

(5) OPTIMIZE(4)

l 寄存器變量:自動(dòng)和參數(shù)變量位于寄存器中,只要有可能,將不為這些就是變量保留數(shù)據(jù)存貯器空間。

l 擴(kuò)展訪問(wèn)優(yōu)化:由IDATA,XDATA和CODE區(qū)域來(lái)的變量直接包含在操作中,因此在大多數(shù)時(shí)候裝入中間寄存器是不必要的。

l 局部公共子式的消除:如果表達(dá)式中有一個(gè)重復(fù)執(zhí)行的計(jì)算,只要有可能,第一次計(jì)算的結(jié)果將被用于后續(xù)的計(jì)算,因此可以從代碼中消除繁雜的計(jì)算。

l CASE/SWITCH優(yōu)化:CASE/SWITCH語(yǔ)句作為跳轉(zhuǎn)表或跳轉(zhuǎn)串被優(yōu)化。

(6) OPTIMIZE(5)

l 全局公共子式消除:只要有可能,函數(shù)內(nèi)相同的子表達(dá)式只計(jì)算一次。中間結(jié)果存入一個(gè)寄存器以代替新的計(jì)算。

l 簡(jiǎn)單循環(huán)優(yōu)化:以常量占據(jù)一段內(nèi)存的循環(huán)被轉(zhuǎn)化并在運(yùn)行時(shí)被優(yōu)化。OPTIMIZE(5)包括了從0級(jí)到4的所有優(yōu)化。

例: C51 SAMPLE.C OPTIMIZE(4)

#pragma ot(5,SIZE)

#pragma ot(size)

注: 全局優(yōu)化從優(yōu)化級(jí)4開(kāi)始。同時(shí),一個(gè)完整的函數(shù)被優(yōu)化時(shí),如果分配給生成優(yōu)

化代碼所必要的數(shù)據(jù)結(jié)構(gòu)的內(nèi)存不夠,全局優(yōu)化只執(zhí)行一部分,或根本不執(zhí)行。

 

2.2.5 SMALL/COMPACT/LARGE

名 字: SMALL/COMPACT/LARGE

縮 寫: 無(wú)

變 量: 無(wú)

默認(rèn)值: SMALL

SMALL,COMPACT,LARGE這些指令控制存貯器模式選擇。存貯器模式對(duì)不同的變量定義有所影響。

SMALL:

所有函數(shù)和過(guò)程變量及局部數(shù)據(jù)段被定義在8051系統(tǒng)內(nèi)部數(shù)據(jù)存貯器,因此以這種模式訪問(wèn)數(shù)據(jù)對(duì)象是非常有效的。這種模式的缺點(diǎn)是地址空間有限。

COMPACT:

所有函數(shù)和過(guò)程變量及局部數(shù)據(jù)段被定義在8051系統(tǒng)外部數(shù)據(jù)存貯器中,這個(gè)存貯區(qū)可達(dá)256字節(jié)(1頁(yè))。這種模式使用訪問(wèn)外部數(shù)據(jù)存貯器的簡(jiǎn)潔形式(@R0/R1)。

LARGE:

所有變量和局部變量數(shù)據(jù)段定義在8051系統(tǒng)的外部數(shù)據(jù)存貯器中,可訪問(wèn)達(dá)64K字節(jié)的地址空間。因此,它需要通過(guò)數(shù)據(jù)指針(DPTR),這是一種效率不高的數(shù)據(jù)訪問(wèn)形式。

注意:調(diào)用子程序的棧始終放在內(nèi)部存貯器中。

例: C51 SAMPLE.C LARGE

#pragma compact

2.2.6 REGPARMS/NOREGPARMS

名 字: REGPARMS/NOREGPARMS

縮 寫: RP/NORP

變 量: 無(wú)

默認(rèn)值: REGPARMS

使用REGPARMS指令時(shí),編譯器在寄存器內(nèi)至多傳遞三個(gè)參數(shù)。該指令產(chǎn)生的參數(shù)傳遞代碼與早期的C51版本兼容。

REGPARMS和NOREGPARMS指令可以在源程序中定義多次。這樣就允許程序的某一節(jié)使用寄存器進(jìn)行參數(shù)傳遞,而其它函數(shù)仍然用原來(lái)的傳遞方式,匯編語(yǔ)言函數(shù)及庫(kù)文件(已經(jīng)存在的)則不必更改。

例: C51 DEMO.C NOREGPARMS

#pragma RP

 

2.2.7 REGISTERBANK

名 字: REGISTERBANK

縮 寫: RB

變 量: 括號(hào)內(nèi)一個(gè)0~3的數(shù)

默認(rèn)值: REGISTERBANK(0)

REGISTERBANK指令選擇當(dāng)前調(diào)用時(shí)使用的寄存器組,除非使用“using”標(biāo)志。當(dāng)能夠計(jì)算寄存器的絕對(duì)數(shù)量時(shí),生成代碼可能使用寄存器訪問(wèn)的絕對(duì)形式,用助記符“Arn”來(lái)表示。

與“using n”相比,REGISTERBANK不轉(zhuǎn)換寄存器組!

有返回值的函數(shù)必須始終使用同一個(gè)寄存器組。否則,返回值可能放在錯(cuò)誤的寄存器組中。

例: C51 DEMO.C REGISTERBANK

#pragma rp(3)

 

2.2.8 AREGS/NOAREGS

名 字: AREGS/NOAREGS

縮 寫: AR/NOAR

變 量: 無(wú)

默認(rèn)值: AREGS

AREGS使編譯器使用絕對(duì)寄存器尋址方式,絕對(duì)寄存器尋址方式提高了效率。例如:PUSH和POP指令只能直接(絕對(duì))尋址。用REGSITERBANK指令可建立指定使用的寄存器組。NOAREG指令關(guān)閉絕對(duì)尋址。未使用NOAREGS指令編譯的函數(shù)不依賴于寄存器組,即它們可使用8051所有的寄存器。AREGS/NOAREGS指令可在程序中定義多次,然而,這只能在函數(shù)外使用。

例: C51 DEMO.C NOAREGS

#pragma AREGS

 

2.2.9 INTVECTOR/NOINTVECTOR

名 字: INTVECTOR/NOINTVECTOR

縮 寫: IV/NOIV

變 量: 無(wú)

默認(rèn)值: INTVECTOR

INTVECTOR指令使編譯器產(chǎn)生3字節(jié)跳轉(zhuǎn)(LJMP)目標(biāo)值。這些向量放在絕對(duì)地址8n+3處,n為中斷號(hào)。NOINTVECTOR指令可以防止產(chǎn)生這些中斷向量,這種靈活性使用戶可以利用其它編程工具提供的中斷服務(wù)子程序。

例: C51 SAMPLE.C NOINTVECTOR

#pragma noiv

 

2.2.10 ROM

ROM指令用來(lái)決定程序內(nèi)存的大小,它影響跳轉(zhuǎn)指令的編碼。

ROM(SMALL):

以CALL和JMP指令作為ACALL和AJMP指令的編碼,最大程序空間可達(dá)2K字節(jié),整個(gè)用戶程序必須分布在這2K字節(jié)空間內(nèi)。

ROM(COMPACT):

CALL指令以LCALL編碼,函數(shù)內(nèi)JMP指令以AJMP編碼,因此函數(shù)長(zhǎng)度不得超過(guò)2K字節(jié),而整個(gè)程序長(zhǎng)度不得超過(guò)64K字節(jié),這種用法必須根據(jù)不同的目的而決定,看其是否比標(biāo)準(zhǔn)設(shè)置ROM(LARGE)效果更佳。

ROM(LARGE)

將CALL和JMP指令以LCALL和LJMP編碼。這樣就允許不加限制地使用整個(gè)地址空間,用戶程序最大可達(dá)64K字節(jié)。

例: C51 DEMO.C ROM(SMALL)

#pragma ROM(SMALL)

2.3 列表控制

2.3.1 LISTINCLUDE

名 字: LISTINCLUDE/NOLISTINCLUDE

縮 寫: LC/NOLC

變 量: 無(wú)

默認(rèn)值: NOLISTINCLUDE

LISTINCLUDE指令導(dǎo)致在列表文件中出現(xiàn)頭文件的內(nèi)容。QTH仿真器建議用戶使用默認(rèn)值。

 

2.3.2 SYMBOLS/NOSYMBOLS

名 字: SYMBOLS/NOSYMBOLS

縮 寫: SB/NOSB

變 量: 無(wú)

默認(rèn)值: NOSYMBOL

SYMBOLS,NOSYMBOLS指令在編譯時(shí)產(chǎn)生一個(gè)被程序模塊使用過(guò)的符號(hào)表。對(duì)于每一個(gè)符號(hào)對(duì)象,包含了存貯器登錄,存貯類型,偏移和對(duì)象大小。

例: C51 DEMO.C SB

#pragma sb

 

2.3.3 PREPRINT/NOPREPRINT

名 字: PREPRINT/NOPREPRINT

縮 寫: PP/NOPP

變 量: 括號(hào)內(nèi)可選的文件名

默認(rèn)值: NOPREPRINT

PREPRINT指令產(chǎn)生一個(gè)預(yù)處理器列表,宏調(diào)用被擴(kuò)展并且注釋被刪除。如果PREPRINT指令不帶變量,則源文件名加上擴(kuò)展名“·I”作為列表文件名,如果不用此名,則須指定一個(gè)文件名。

例: C51 DEMO.C PP(DEMO.LST)

 

2.3.4 CODE/NOCODE

名 字: CODE/NOCODE

縮 寫: CD/NOCD

變 量: 無(wú)

默認(rèn)值: NOCODE

CODE指令在列表文件后附加上一個(gè)匯編記憶表,源程序中的每個(gè)函數(shù)被表示為匯編代碼。

 

2.3.5 PRINT/NOPRINT

名 字: PRINT/NOPRINT

縮 寫: PR/NOPR

變 量: 括號(hào)內(nèi)文件名

默認(rèn)值: PRINT(bname.LST)

PRINT指令使編譯器用路徑,源文件名及擴(kuò)展名“.LST”為每個(gè)被編譯的程序產(chǎn)生一個(gè)列表文件,該列表文件名可以用PRINT選項(xiàng)重新定義,當(dāng)使用NOPRINT時(shí),將不產(chǎn)生列表文件。QTH仿真器建議用戶使用默認(rèn)值。

 

2.3.6 COND/NOCOND

名 字: COND/NOCOND

縮 寫: CO/NOCO

變 量: 無(wú)

默認(rèn)值: COND

指令COND和NOCOND決定源文件中條件編譯部分是否出現(xiàn)在列表文件中,COND選項(xiàng)禁止向列表文件輸出跳過(guò)的行。每當(dāng)預(yù)處理器檢測(cè)到該指令時(shí),該指令就會(huì)對(duì)該行產(chǎn)生影響。QTH仿真器建議用戶使用默認(rèn)值。

 

2.3.7 PAGELENGTH

名 字: PAGELENGTH

縮 寫: PL

變 量: 括號(hào)內(nèi)一個(gè)最大為65535十進(jìn)制數(shù)

默認(rèn)值: PAGELENGTH(69)

PAGELENGTH指令指定了列表文件中每頁(yè)的行數(shù)。默認(rèn)值為69頁(yè)。包括抬頭和空行。

例: C51 DEMO.C PAGELENGTH(60)

#pragma pl(60)

 

2.3.8 PAGEWIDTH

名 字: PAGEWIDTH

縮 寫: PW

變 量: 括號(hào)內(nèi)一個(gè)78~132的十進(jìn)制數(shù)

默認(rèn)值: PATHWIDTH(132)

PAGEWIDTH指定了每行的字符數(shù)。若超過(guò)此數(shù),該行將變?yōu)閮尚谢蚨嘈小TH仿真器建議用戶使用默認(rèn)值。

 

2.3.9 EJECT

名 字: EJECT

縮 寫: EJ

變 量: 無(wú)

默認(rèn)值: 無(wú)

EJECT指令使列表文件換頁(yè)。該指令只能用在源文件上,且必須是#pragma的一部分。

 

3 C庫(kù)函數(shù)

C-51軟件包的庫(kù)包含標(biāo)準(zhǔn)的應(yīng)用程序,每個(gè)函數(shù)都在相應(yīng)的頭文件(.h)中有原型聲明。如果使用庫(kù)函數(shù),必須在源程序中用預(yù)編譯指令定義與該函數(shù)相關(guān)的頭文件(包含了該函數(shù)的原型聲明)。例如:

#include

#include

如果省掉頭文件,編譯器則期望標(biāo)準(zhǔn)的C參數(shù)類型,從而不能保證函數(shù)的正確執(zhí)行。

3.1 CTYPE.H:字符函數(shù)

在CTYPE.H頭文件中包含下列一些庫(kù)函數(shù):

 

函數(shù)名: isalpha

原 型: extern bit isalpha(char)

功 能: isalpha檢查傳入的字符是否在‘A’-‘Z’和‘a’-‘z’之間,如果為真返回

值為1,否則為0。

 

函數(shù)名: isalnum

原 型: extern bit isalnum(char)

功 能: isalnum檢查字符是否位于‘A’-‘Z’,‘a’-‘z’或‘0’-‘9’之間,為真返

回值是1,否則為0。

 

函數(shù)名: iscntrl

原 型: extern bit iscntrl(char)

功 能: iscntrl檢查字符是否位于0x00~0x1F之間或0x7F,為真返回值是1,否則為0。

 

函數(shù)名: isdigit

原 型: extern bit isdigit(char)

功 能: isdigit檢查字符是否在‘0’-‘9’之間,為真返回值是1,否則為0。

 

函數(shù)名: isgraph

原 型: extern bit isgraph(char)

功 能: isgraph檢查變量是否為可打印字符,可打印字符的值域?yàn)?x21~0x7E。若為可

打印,返回值為1,否則為0。

 

函數(shù)名: isprint

原 型: extern bit isprint(char)

功 能: 除與isgraph相同外,還接受空格字符(0X20)。

 

函數(shù)名: ispunct

原 型: extern bit ispunct(char)

功 能: ispunct檢查字符是否位為標(biāo)點(diǎn)或空格。如果該字符是個(gè)空格或32個(gè)標(biāo)點(diǎn)和格式

字符之一(假定使用ASCII字符集中128個(gè)標(biāo)準(zhǔn)字符),則返回1,否則返回0。Ispunct對(duì)下列字符返回1:

(空格)!“$%^&()+,-./:<=>?_[‘~{

}

 

函數(shù)名: islower

原 型: extern bit islower(char)

功 能: islower檢查字符變量是否位于‘a’-‘z’之間,為真返回值是1,否則為0。

 

函數(shù)名: isupper

原 型: extern bit isupper(char)

功 能: isupper檢查字符變量是否位于‘A’-‘Z’之間,為真返回值是1,否則為0。

 

函數(shù)名: isspace

原 型: extern bit isspace(char)

功 能: isspace檢查字符變量是否為下列之一:空格、制表符、回車、換行、垂直制表

符和送紙。為真返回值是1,否則為0。

 

函數(shù)名: isxdigit

原 型: extern bit isxdigit(char)

功 能: isxdigit檢查字符變量是否位于‘0’-‘9’,‘A’-‘F’或‘a’-‘f’之間,

為真返回值是1,否則為0。

 

函數(shù)名: toascii

原 型: toascii(c)((c)&0x7F);

功 能: 該宏將任何整型值縮小到有效的ASCII范圍內(nèi),它將變量和0x7F相與從而去掉低

7位以上所有數(shù)位。

 

函數(shù)名: toint

原 型: extern char toint(char)

功 能: toint將ASCII字符轉(zhuǎn)換為16進(jìn)制,返回值0到9由ASCII字符‘0’到‘9’得

到,10到15由ASCII字符‘a’-‘f’(與大小寫無(wú)關(guān))得到。

函數(shù)名: tolower

原 型: extern char tolower(char)

功 能: tolower將字符轉(zhuǎn)換為小寫形式,如果字符變量不在‘A’-‘Z’之間,則不作轉(zhuǎn)

換,返回該字符。

 

函數(shù)名: ­_tolower

原 型: tolower(c);(c-‘A’+‘a’)

功 能: 該宏將0x20參量值逐位相或。

 

函數(shù)名: toupper

原 型: extern char toupper(char)

功 能: toupper將字符轉(zhuǎn)換為大寫形式,如果字符變量不在‘a’-‘z’之間,則不作轉(zhuǎn)

換,返回該字符。

 

函數(shù)名: _toupper

原 型: _toupper(c);((c)-‘a’+’A’)

功 能: _toupper宏將c與0xDF逐位相與。

3.2 STDIO.H:一般I/O函數(shù)

C51編譯器包含字符I/O函數(shù),它們通過(guò)處理器的串行接口操作,為支持其它I/O機(jī)制,只需修改getkey()和putchar()函數(shù),其它所有I/O支持函數(shù)依賴這兩個(gè)模塊,不需要改動(dòng)。在使用8051串行口之前,必須將它們初始化,下例以2400波特率,12MHz初始化串口:

SCON=0x52 /*SCON*/

TMOD=0x20 /*TMOD*/

TR1=1 /*Timer 1 run flag*/

TH1=0Xf3 /*TH1*/

其它工作模式和波特率等細(xì)節(jié)問(wèn)題可以從8051用戶手冊(cè)中得到。

 

函數(shù)名: _getkey

原 型: extern char _getkey();

功 能: _getkey()從8051串口讀入一個(gè)字符,然后等待字符輸入,這個(gè)函數(shù)是改變整個(gè)

輸入端口機(jī)制應(yīng)作修改的唯一一個(gè)函數(shù)。

 

函數(shù)名: getchar

原 型: extern char _getchar();

功 能: getchar()使用_getkey從串口讀入字符,除了讀入的字符馬上傳給putchar函數(shù)

以作響應(yīng)外,與_getkey相同。

 

函數(shù)名: gets

原 型: extern char *gets(char *s,int n);

功 能: 該函數(shù)通過(guò)getchar從控制臺(tái)設(shè)備讀入一個(gè)字符送入由‘s’指向的數(shù)據(jù)組???/p>

慮到ANSI標(biāo)準(zhǔn)的建議,限制每次調(diào)用時(shí)能讀入的最大字符數(shù),函數(shù)提供了一個(gè)字符計(jì)數(shù)器‘n’,在所有情況下,當(dāng)檢測(cè)到換行符時(shí),放棄字符輸入。

 

函數(shù)名: ungetchar

原 型: extern char ungetchar(char);

功 能: ungetchar將輸入字符推回輸入緩沖區(qū),因此下次gets或getchar可用該字符。

ungetchar成功時(shí)返回‘char’,失敗時(shí)返回EOF,不可能用ungetchar處理多個(gè)字符。

 

函數(shù)名: _ungetchar

原 型: extern char _ungetchar(char);

功 能: _ungetchar將傳入字符送回輸入緩沖區(qū)并將其值返回給調(diào)用者,下次使用getkey

時(shí)可獲得該字符,寫回多個(gè)字符是不可能的。

 

函數(shù)名: putchar

原 型: extern putchar(char);

功 能: putchar通過(guò)8051串口輸出‘char’,和函數(shù)getkey一樣,putchar是改變整個(gè)

輸出機(jī)制所需修改的唯一一個(gè)函數(shù)。

 

函數(shù)名: printf

原 型: extern int printf(const char*,…);

功 能: printf以一定格式通過(guò)8051串口輸出數(shù)值和串,返回值為實(shí)際輸出的字符數(shù),

參量可以是指針、字符或數(shù)值,第一個(gè)參量是格式串指針。

注:允許作為printf參量的總字節(jié)數(shù)由C51庫(kù)限制,因?yàn)?051結(jié)構(gòu)上存貯空間有限,在SMALL和COMPACT模式下,最大可傳遞15個(gè)字節(jié)的參數(shù)(即5個(gè)指針,或1個(gè)指針和3個(gè)長(zhǎng)字節(jié)),在LARGE模式下,至多可傳遞40個(gè)字節(jié)的參數(shù)。格式控制串包含下列域(方括號(hào)內(nèi)的域是可能的):

%[flags][width][.precision]type

“width”域定義了參量欲顯示的字符數(shù),它必須是一個(gè)十進(jìn)制數(shù),如果實(shí)際顯示的字符數(shù)小于“width”,輸出左端補(bǔ)以空格,如果“width”域以0開(kāi)始,則左端補(bǔ)0。

“flag”域用來(lái)定義下面選項(xiàng):

 

 

Falg

 

意 義

 

-

 

輸出左齊

 

+

 

輸出值如果是有符號(hào)數(shù)值,則加上+/-號(hào)

 

‘ ‘(空格)

 

輸出值如果為正則左邊補(bǔ)以空格顯示

 

#

 

如果它與0,x或X聯(lián)用,則在輸出前加上字符0、0x,0X。當(dāng)與值類型g、G、f、e、E聯(lián)用時(shí),‘#’使輸出數(shù)產(chǎn)生一個(gè)十進(jìn)制小數(shù)點(diǎn)。

 

b,B

 

它們與格式類型d、i、o、u、x、X聯(lián)用,這樣參量類型被接受為‘[unsigned]char’,如:%bu,%bd或%bx。

 

L,L

 

它們與格式類型d、i、o、u、x、X聯(lián)用,這樣參量類型被接受為‘[unsigned]long’,如:%lu,%ld或%lx。

 

*

 

下一個(gè)參量不作輸出。

 

 

“type“域定義參量如下類型:

 

 

字 符

 

類 型

 

輸 出 格 式

 

d

 

int

 

有符號(hào)十進(jìn)制數(shù)(16位)

 

U

 

int

 

無(wú)符號(hào)十進(jìn)制數(shù)

 

o

 

int

 

無(wú)符號(hào)八進(jìn)制數(shù)

 

X,x

 

int

 

無(wú)符號(hào)十六進(jìn)制數(shù)

 

f

 

float

 

[-]dddd.dddd形式的浮點(diǎn)數(shù)

 

e,E

 

float

 

[-]d.ddddE[sign]dd形式的浮點(diǎn)數(shù)

 

g,G

 

float

 

e或f形式浮點(diǎn)數(shù),看哪一種輸出形式好。

 

c

 

char

 

字符

 

s

 

pointer

 

指向一個(gè)帶結(jié)束符號(hào)的串

 

p

 

pointer

 

帶存貯器指示符和偏移的指針。M:aaaa。

M:=C(ode),D(ata),I(data),P(data) aaaa:指針偏移值。

 

 

例子:

printf(“Int-Val%d,Char-Val%bd,Long-Val%d”,I,c,l);

printf(“String%s,Character%c”,array,character);

printf(“Pointer%p”,&array[10]);

 

函數(shù)名: sprintf

原 型: extern int sprintf(char *s,const char*,…);

功 能: sprintf與printf相似,但輸出不顯示在控制臺(tái)上,而是通過(guò)一個(gè)指針S,送入

可尋址的緩沖區(qū)。

注:sprintf允許輸出的參量總字節(jié)數(shù)與printf完全相同。

 

函數(shù)名: puts

原 型: extern int puts(const char*,…);

功 能: puts將串‘s’和換行符寫入控制臺(tái)設(shè)備,錯(cuò)誤時(shí)返回EOF,否則返回一非負(fù)數(shù)。

 

函數(shù)名: scanf

原 型: extern int scanf(const char*,…);

功 能: scanf在格式串控制下,利用getcha函數(shù)由控制臺(tái)讀入數(shù)據(jù),每遇到一個(gè)值(符

號(hào)格式串規(guī)定),就將它按順序賦給每個(gè)參量,注意每個(gè)參量必須都是指針。scanf返回它所發(fā)現(xiàn)并轉(zhuǎn)換的輸入項(xiàng)數(shù)。若遇到錯(cuò)誤返回EOF。格式串包括:

l 空格、制表符等,這些空白字符被忽略。

l 字符,除需匹配的“%”(格式控制字符)外。

l 轉(zhuǎn)換指定字符“%”,后隨幾個(gè)可選字符;賦值抑制符“*”,一個(gè)指定最大域?qū)挼臄?shù)。

注:scanf參量允許的總字節(jié)數(shù)與printf相同,格式控制串可包括下列域(方括號(hào)內(nèi)是可選的):

%[flags][width]type

格式串總是以百分號(hào)開(kāi)始,每個(gè)域包含一個(gè)或多個(gè)字符或數(shù)。

“width”域定義了參量可接受的字符數(shù),“width”必須是一個(gè)正十進(jìn)制數(shù)。如果實(shí)際輸入字符數(shù)量小于“width”,則不會(huì)進(jìn)行填充。

‘flag’域用來(lái)定義下面選項(xiàng):

 

 

Flag

 

意 義

 

*

 

輸入被忽略

 

b,h

 

它們用作格式類型d,i,o,u和x的前綴,用這些變量可定義參量是字符指針還是無(wú)符號(hào)字符指針。如%bu,%bd,%bx。

 

L

 

它們被作格式類型d,i,o,u和x的前綴,使用這個(gè)前綴可定義參量是長(zhǎng)指針還是無(wú)符號(hào)字長(zhǎng)指針。如%lu,%ld,%lx。

 

 

“type”域定義參量為如下類型:

 

 

描 述 符

 

類 型

 

輸 入 格 式

 

d

 

ptr to int

 

有符號(hào)十進(jìn)制數(shù)(16位)

 

i

 

ptr to int

 

如C中記號(hào)一樣,整型值

 

u

 

ptr to int

 

無(wú)符號(hào)十進(jìn)制數(shù)

 

o

 

ptr to int

 

無(wú)符號(hào)八進(jìn)制數(shù)

 

x

 

ptr to int

 

無(wú)符號(hào)十六進(jìn)制數(shù)

 

f,e,g

 

ptr to float

 

浮點(diǎn)數(shù)

 

c

 

ptr to char

 

一個(gè)字符

 

s

 

ptr to string

 

一個(gè)字串

 

例子:

scanf(“%d%bd%ld”,&i,&c,&l);

scanf(“%f”,&f);

scanf(“%3s,%c”,&string[0],&character);

 

函數(shù)名: sscanf

原 型: extern int sscanf(const *s,const char*,…);

功 能: sscanf與scanf方式相似,但串輸入不是通過(guò)控制臺(tái),而是通過(guò)另一個(gè)以空結(jié)束

的指針。

注:sscanf參量允許的總字節(jié)數(shù)由C-51庫(kù)限制,這是因?yàn)?051處理器結(jié)構(gòu)內(nèi)存的限制,在SMALL和COMPACT模式,最大允許15字節(jié)參數(shù)(即至多5個(gè)指針,或2個(gè)指針,2個(gè)長(zhǎng)整型或1個(gè)字符型)的傳遞。在LARGE模式下,最大允許傳送40個(gè)字節(jié)的參數(shù)。

3.3 STRING.H:串函數(shù)

串函數(shù)通常將指針串作輸入值。一個(gè)串就包括2個(gè)或多個(gè)字符。串結(jié)以空字符表示。在函數(shù)memcmp,memcpy,memchr,memccpy,memmove和memset中,串長(zhǎng)度由調(diào)用者明確規(guī)定,使這些函數(shù)可工作在任何模式下。

 

函數(shù)名: memchr

原 型: extern void *memchr(void *sl, char val,int len);

功 能: memchr順序搜索s1中的len個(gè)字符找出字符val,成功時(shí)返回s1中指向val的

指針,失敗時(shí)返回NULL。

 

函數(shù)名: memcmp

原 型: extern char memcmp(void *sl, void *s2,int len);

功 能: memcmp逐個(gè)字符比較串s1和s2的前l(fā)en個(gè)字符。相等時(shí)返回0,如果串s1大

于或小于s2,則相應(yīng)返回一個(gè)正數(shù)或負(fù)數(shù)。

 

 

函數(shù)名: memcpy

原 型: extern void *memcpy(void *dest, void *src,int len);

功 能: memcpy由src所指內(nèi)存中拷貝len個(gè)字符到dest中,返回批向dest中的最后一

個(gè)字符的指針。如果src和dest發(fā)生交迭,則結(jié)果是不可預(yù)測(cè)的。

 

函數(shù)名: memccpy

原 型: extern void *memccpy(void *dest, void *src,char val,int len);

功 能: memccpy拷貝src中l(wèi)en個(gè)字符到dest中,如果實(shí)際拷貝了len個(gè)字符返回NULL。

拷貝過(guò)程在拷貝完字符val后停止,此時(shí)返回指向dest中下一個(gè)元素的指針。

 

函數(shù)名: memmove

原 型: extern void *memmove(void *dest, void *src,int len);

功 能: memmove工作方式與memcpy相同,但拷貝區(qū)可以交迭。

 

函數(shù)名: memset

原 型: extern void *memset(void *s, char val,int len);

功 能: memset 將val值填充指針s中l(wèi)en個(gè)單元。

 

函數(shù)名: strcat

原 型: extern char *strcat(char *s1, char *s2);

功 能: strcat將串s2拷貝到串s1結(jié)尾。它假定s1定義的地址區(qū)足以接受兩個(gè)串。返

回指針指向s1串的第一字符。

 

函數(shù)名: strncat

原 型: extern char *strncat(char *s1, char *s2,int n);

功 能: strncat拷貝串s2中n個(gè)字符到串s1結(jié)尾。如果s2比n短,則只拷貝s2。

 

函數(shù)名: strcmp

原 型: extern char strcmp(char *s1, char *s2);

功 能: strcmp比較串s1和s2,如果相等返回0,如果s1s2則返回

一個(gè)正數(shù)。

 

函數(shù)名: strncmp

原 型: extern char strncmp(char *s1, char *s2,int n);

功 能: strncmp比較串s1和s2中前n個(gè)字符,返回值與strncmp相同。

 

函數(shù)名: strcpy

原 型: extern char *strcpy(char *s1, char *s2);

功 能: strcpy將串s2包括結(jié)束符拷貝到s1,返回指向s1的第一個(gè)字符的指針。

 

函數(shù)名: strncpy

原 型: extern char *strncpy(char *s1, char *s2,int n);

功 能: strncpy與strcpy相似,但只拷貝n個(gè)字符。如果s2長(zhǎng)度小于n,則s1串以‘0’

補(bǔ)齊到長(zhǎng)度n。

 

函數(shù)名: strlen

原 型: extern int strlen(char *s1);

功 能: strlen返回串s1字符個(gè)數(shù)(包括結(jié)束字符)。

函數(shù)名: strchr,strpos

原 型: extern char *strchr(char *s1, char c);

extern int strpos(char *s1,char c);

功 能: strchr搜索s1串中第一個(gè)出現(xiàn)的‘c’字符,如果成功,返回指向該字符的別指

針,搜索也包括結(jié)束符。搜索一個(gè)空字符返回指向空字符的指針而不是空指針。

strpos與strchr相似,但它返回字符在串中的位置或-1,s1串的第一個(gè)字符位置是0。

 

函數(shù)名: strrchr,strrpos

原 型: extern char *strrchr(char *s1, char c);

extern int strrpos(char *s1,char c);

功 能: strrchr搜索s1串中最后一個(gè)出現(xiàn)的‘c’字符,如果成功,返回指向該字符的

指針,否則返回NULL。對(duì)s1搜索也返回指向字符的指針而不是空指針。

strrpos與strrchr相似,但它返回字符在串中的位置或-1。

 

函數(shù)名: strspn,strcspn,strpbrk,strrpbrk

原 型: extern int strspn(char *s1, char *set);

extern int strcspn(char *s1,char *set);

extern char *strpbrk(char *s1,char *set);

extern char *strpbrk(char *s1,char *set);

功 能: strspn搜索s1串中第一個(gè)不包含在set中的字符,返回值是s1中包含在set里

字符的個(gè)數(shù)。如果s1中所有字符都包含在set里,則返回s1的長(zhǎng)度(包括結(jié)束符)。如果s1是空串,則返回0。

strcspn與strspn類似,但它搜索的是s1串中的第一個(gè)包含在set里的字符。strpbrk與strspn很相似,但它返回指向搜索到字符的指針,而不是個(gè)數(shù),如果未找到,則返回NULL。

strrpbrk與strpbrk相似,但它返回s1中指向找到的set字集中最后一個(gè)字符的指針。

3.4 STDLIB.H:標(biāo)準(zhǔn)函數(shù)

函數(shù)名: atof

原 型: extern double atof(char *s1);

功 能: atof將s1串轉(zhuǎn)換為浮點(diǎn)值并返回它。輸入串必須包含與浮點(diǎn)值規(guī)定相符的數(shù)。

C51編譯器對(duì)數(shù)據(jù)類型float和double相同對(duì)待。

 

函數(shù)名: atol

原 型: extern long atol(char *s1);

功 能: atol將s1串轉(zhuǎn)換成一個(gè)長(zhǎng)整型值并返回它。輸入串必須包含與長(zhǎng)整型值規(guī)定相

符的數(shù)。

 

函數(shù)名: atoi

原 型: extern int atoi(char *s1);

功 能: atoi將s1串轉(zhuǎn)換為整型數(shù)并返回它。輸入串必須包含與整型數(shù)規(guī)定相符的數(shù)。

3.5 MATH.H:數(shù)學(xué)函數(shù)

函數(shù)名: abs,cabs,fabs,labs

原 型: extern int abs(int va1);

extern char cabs(char val);

extern float fabs(float val);

extern long labs(long val);

功 能: abs決定了變量val的絕對(duì)值,如果val為正,則不作改變返回;如果為負(fù),則

返回相反數(shù)。這四個(gè)函數(shù)除了變量和返回值的數(shù)據(jù)不一樣外,它們功能相同。

 

函數(shù)名: exp,log,log10

原 型: extern float exp(float x);

extern float log(float x);

extern float log10(float x);

功 能:exp返回以e為底x的冪,log返回x的自然數(shù)(e=2.718282),log10返回x以10

為底的數(shù)。

 

函數(shù)名: sqrt

原 型: extern float sqrt(float x);

功 能: sqrt返回x的平方根。

 

函數(shù)名:rand,srand

原 型: extern int rand(void);

extern void srand(int n);

功 能: rand返回一個(gè)0到32767之間的偽隨機(jī)數(shù)。srand用來(lái)將隨機(jī)數(shù)發(fā)生器初始化成

一個(gè)已知(或期望)值,對(duì)rand的相繼調(diào)用將產(chǎn)生相同序列的隨機(jī)數(shù)。

函數(shù)名: cos,sin,tan

原 型: extern float cos(flaot x);

extern float sin(flaot x);

extern flaot tan(flaot x);

功 能: cos返回x的余弦值。Sin返回x的正弦值。tan返回x的正切值,所有函數(shù)變量

范圍為-π/2~+π/2,變量必須在±65535之間,否則會(huì)產(chǎn)生一個(gè)NaN錯(cuò)誤。

 

 

函數(shù)名: acos,asin,atan,atan2

原 型: extern float acos(float x);

extern float asin(float x);

extern float atan(float x);

extern float atan(float y,float x);

功 能: acos返回x的反余弦值,asin返回x的正弦值,atan返回x的反正切值,它們

的值域?yàn)?π/2~+π/2。atan2返回x/y的反正切,其值域?yàn)?π~+π。

 

函數(shù)名: cosh,sinh,tanh

原 型: extern float cosh(float x);

extern float sinh(float x);

extern float tanh(float x);

功 能: cosh返回x的雙曲余弦值;sinh返回x的雙曲正弦值;tanh返回x的雙曲正切

值。

 

函數(shù)名: fpsave,fprestore

原 型: extern void fpsave(struct FPBUF *p);

extern void fprestore (struct FPBUF *p);

功 能: fpsave保存浮點(diǎn)子程序的狀態(tài)。fprestore將浮點(diǎn)子程序的狀態(tài)恢復(fù)為其原始狀

態(tài),當(dāng)用中斷程序執(zhí)行浮點(diǎn)運(yùn)算時(shí)這兩個(gè)函數(shù)是有用的。

3.6 ABSACC.H:絕對(duì)地址訪問(wèn)

函數(shù)名: CBYTE,DBYTE,PBYTE,XBYTE

原 型: #define CBYTE((unsigned char *)0x50000L)

#define DBYTE((unsigned char *)0x40000L)

#define PBYTE((unsigned char *)0x30000L)

#define XBYTE((unsigned char *)0x20000L)

功 能: 上述宏定義用來(lái)對(duì)8051地址空間作絕對(duì)地址訪問(wèn),因此,可以字節(jié)尋址。CBYTE

尋址CODE區(qū),DBYTE尋址DATA區(qū),PBYTE尋址XDATA區(qū)(通過(guò)MOVX @R0命令),XBYTE尋址XDATA區(qū)(通過(guò)MOVX @DPTR命令)。

例:下列指令在外存區(qū)訪問(wèn)地址0x1000

xval=XBYTE[0x1000];

XBYTE[0X1000]=20;

通過(guò)使用#define指令,用符號(hào)可定義絕對(duì)地址,如符號(hào)X10可與XBYTE[0x1000]地址相等:#define X10 XBYTE[0x1000]。

 

函數(shù)名: CWORD,DWORD,PWORD,XWORD

原 型: #define CWORD((unsigned int *)0x50000L)

#define DWORD((unsigned int *)0x40000L)

#define PWORD((unsigned int *)0x30000L)

#define XWORD((unsigned int *)0x20000L)

功 能:這些宏與上面相似,只是它們指定的類型為unsigned int。通過(guò)靈活的數(shù)據(jù)類型,

所有地址空間都可以訪問(wèn)。

3.7 INTRINS.H:內(nèi)部函數(shù)

函數(shù)名: _crol_,_irol_,_lrol_

原 型: unsigned char _crol_(unsigned char val,unsigned char n);

unsigned int _irol_(unsigned int val,unsigned char n);

unsigned int _lrol_(unsigned int val,unsigned char n);

功 能:_crol_,_irol_,_lrol_以位形式將val左移n位,該函數(shù)與8051“RLA”指令

相關(guān),上面幾個(gè)函數(shù)不同于參數(shù)類型。

例:

#include

main()

{

unsigned int y;

y=0x00ff;

y=_irol_(y,4); /*y=0x0ff0*/

}

 

函數(shù)名: _cror_,_iror_,_lror_

原 型: unsigned char _cror_(unsigned char val,unsigned char n);

unsigned int _iror_(unsigned int val,unsigned char n);

unsigned int _lror_(unsigned int val,unsigned char n);

功 能:_cror_,_iror_,_lror_以位形式將val右移n位,該函數(shù)與8051“RRA”指令

相關(guān),上面幾個(gè)函數(shù)不同于參數(shù)類型。

例:

#include

main()

{

unsigned int y;

y=0x0ff00;

y=_iror_(y,4); /*y=0x0ff0*/

}

 

函數(shù)名: _nop_

原 型: void _nop_(void);

功 能:_nop_產(chǎn)生一個(gè)NOP指令,該函數(shù)可用作C程序的時(shí)間比較。C51編譯器在_nop_函

數(shù)工作期間不產(chǎn)生函數(shù)調(diào)用,即在程序中直接執(zhí)行了NOP指令。

例:

P()=1;

_nop_();

P()=0;

函數(shù)名: _testbit_

原 型:bit _testbit_(bit x);

功 能:_testbit_產(chǎn)生一個(gè)JBC指令,該函數(shù)測(cè)試一個(gè)位,當(dāng)置位時(shí)返回1,否則返回0。

如果該位置為1,則將該位復(fù)位為0。8051的JBC指令即用作此目的。 _testbit_只能用于可直接尋址的位;在表達(dá)式中使用是不允許的。

STDARG.H:變量參數(shù)表

C51編譯器允許再入函數(shù)的變量參數(shù)(記號(hào)為“…”)。頭文件STDARG.H允許處理函數(shù)的參數(shù)表,在編譯時(shí)它們的長(zhǎng)度和數(shù)據(jù)類型是未知的。為此,定義了下列宏。

 

宏 名: va_list

功 能: 指向參數(shù)的指針。

 

宏 名: va_stat(va_list pointer,last_argument)

功 能: 初始化指向參數(shù)的指針。

 

宏 名: type va_arg(va_list pointer,type)

功 能:返回類型為type的參數(shù)。

 

宏 名: va_end(va_list pointer)

功 能: 識(shí)別表尾的啞宏。

3.8 SETJMP.H:全程跳轉(zhuǎn)

Setjmp.h中的函數(shù)用作正常的系列數(shù)調(diào)用和函數(shù)結(jié)束,它允許從深層函數(shù)調(diào)用中直接返回。

 

函數(shù)名: setjmp

原 型: int setjmp(jmp_buf env);

功 能: setjmp將狀態(tài)信息存入env供函數(shù)longjmp使用。當(dāng)直接調(diào)用setjmp 時(shí)返回值

是0,當(dāng)由longjmp調(diào)用時(shí)返回非零值,setjmp只能在語(yǔ)句IF或SWITCH中調(diào)用一次。

 

函數(shù)名: long jmp

原 型: long jmp(jmp_buf env,int val);

功 能:longjmp恢復(fù)調(diào)用setjmp時(shí)存在env中的狀態(tài)。程序繼續(xù)執(zhí)行,似乎函數(shù)setjmp

已被執(zhí)行過(guò)。由setjmp返回的值是在函數(shù)longjmp中傳送的值val,由setjmp調(diào)用的函數(shù)中的所有自動(dòng)變量和未用易失性定義的變量的值都要改變。

3.9 REGxxx.H:訪問(wèn)SFR和SFR-BIT地址

文件REG51.H,REG52.H和REG552.H允許訪問(wèn)8051系列的SFR和SFR-bit的地址,這些文件都包含#include指令,并定義了所需的所有SFR名以尋址8051系列的外圍電路地址,對(duì)于8051系列中其它一些器件,用戶可用文件編輯器容易地產(chǎn)生一個(gè)“.h”文件。

下例表明了對(duì)8051 PORT0和PORT1的訪問(wèn):

#include

main() {

if(p0==0x10) p1=0x50;

}

 

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉