(玩(wan)電子) 電子技(ji)術學習與研究
當前位置︰單片機教程(cheng)網 >> 基礎(chu)教程(cheng) >> 瀏(liu)覽文章(zhang)

网上彩票代理官网

作者:佚(die)名   來源:本站原創   點擊數:x  更新(xin)lv)奔洌007年07月18日(ri)   【字體︰
  上課(ke)所提到變量就是(shi)一種在程(cheng)序執行過程(cheng)中其值de)懿歡媳浠 de)量。要在程(cheng)序中使用變量必須先用標識符作為變量名,並(bing)指(zhi)出所用的(de)數據類型和(he)存儲模式,這樣編譯系di)巢拍  淞糠峙pei)相(xiang)應(ying)的(de)存儲空(kong)間。定義一個(ge)變量的(de)格式如(ru)下(xia)︰
    [存儲種類] 數據類型 [存儲器類型] 變量名表
  在定義格式中除(chu)了數據類型和(he)變量名表是(shi)必要的(de),其它都是(shi)可選項(xiang)。存儲種類有四種︰自(zi)動(auto),外部(extern),靜態(static)和(he)寄存器(register),缺省類型為自(zi)動(auto)。這些存儲種類的(de)具體含(han)義和(he)使用方法(fa),將在第七課(ke)《變量的(de)存儲》中進(jin)一步進(jin)行學習。
  而這里的(de)數據類型則是(shi)和(he)我們在第四課(ke)中學習到的(de)名種數據類型的(de)定義是(shi)一樣的(de)。說明了一個(ge)變量的(de)數據類型後,還可選擇說明該變量的(de)存儲器類型。存儲器類型的(de)說明就是(shi)指(zhi)定該變量在單片機c語言硬(ying)件系di)持(chi)興褂玫de)存儲區域,並(bing)在編譯時(shi)準確的(de)定位。表6-1中是(shi)KEIL uVision2所能認別的(de)存儲器類型。注意的(de)是(shi)在AT89c51芯片中RAM只有低(di)128位,位于80H到FFH的(de)高128位則在52芯片中才有用,並(bing)和(he)特殊寄存器地(di)址重疊。特殊寄存器(SFR)的(de)地(di)址fan)砬 錘鉸級T89c51特殊功能寄存器列表

表6-1 存儲器類型

存儲器類型

說 明

data

直接(jie)訪問內部數據存儲器(128字節(jie)),訪問速度(du)最(zui)快

bdata

可位尋址內部數據存儲器(16字節(jie)),允許位與字節(jie)混合訪問

idata

間接(jie)訪問內部數據存儲器(256字節(jie)),允許訪問全部內部地(di)址

pdata

分頁(ye)訪問shi)獠渴荽媧?鰨56字節(jie)),用MOVX @Ri指(zhi)令訪問

xdata

外部數據存儲器(64KB),用MOVX @DPTR指(zhi)令訪問

code

程(cheng)序存儲器(64KB),用MOVC @A+DPTR指(zhi)令訪問

 


  如(ru)果省略(lue)存儲器類型,系di)吃蚧hui)按編譯模式SMALL,COMPACT或(huo)LARGE所規(gui)定的(de)默(mo)認存儲器類型去指(zhi)定變量的(de)存儲區域。無論什麼存儲模式都能聲明變量在任何的(de)8051存儲區範圍,然而把最(zui)常用的(de)命令如(ru)循環計(ji)數器和(he)隊列索引放在內部數據區能顯著的(de)提高系di)承閱塴;褂幸 zhi)出的(de)就是(shi)變量的(de)存儲種類與存儲器類型是(shi)完全無關的(de)。

. 數據存儲模式
存儲模式決定了沒有明確指(zhi)定存儲類型的(de)變量,函數參數等的(de)缺省存儲區域,共三種︰
1. 1. Small模式
所有缺省變量參數均裝入內部RAM,優點是(shi)訪問速度(du)快,缺點是(shi)空(kong)間有限,只適用于小程(cheng)序。
2. 2. Compact模式
所有缺省變量均位于外部RAM區的(de)一頁(ye)(256Bytes),具體哪(na)一頁(ye)可由P2口指(zhi)定,在STARTUP.A51文件中說明,也可用pdata指(zhi)定,優點是(shi)空(kong)間較(jiao)Small為寬裕速度(du)較(jiao)Small慢,較(jiao)large要快,是(shi)一種中間狀態。
3. 3. large模式
所有缺省變量可放在多達64KB的(de)外部RAM區,優點是(shi)空(kong)間大,可存變量多,缺點是(shi)速度(du)較(jiao)xia)br />提示︰存儲模式在單片機c語言編譯器選項(xiang)中選擇。

  之前提到簡(jian)單提到sfr,sfr16,sbit定義變量的(de)方法(fa),下(xia)面我們再(zai)來仔細看看chu)br />  sfr和(he)sfr16能直接(jie)對(dui)51單片機的(de)特殊寄存器進(jin)行定義,定義方法(fa)如(ru)下(xia)︰
    sfr 特殊功能寄存器名= 特殊功能寄存器地(di)址常數;
    sfr16 特殊功能寄存器名= 特殊功能寄存器地(di)址常數;
  我們能這樣定義AT89c51的(de)P1口
    sfr P1 = 0x90; //定義P1 I/O口,其地(di)址90H
  sfr關鍵定後面是(shi)一個(ge)要定義的(de)名字,可任意選取,但要符合標識符的(de)命名規(gui)則,名字最(zui)好有一定的(de)含(han)義如(ru)P1口能用P1為名,這樣程(cheng)序會(hui)變的(de)好讀好多。等號後面必須是(shi)常數,不允許有帶(dai)運算(suan)符的(de)表達式,而且該常數必須在特殊功能寄存器的(de)地(di)址範圍之內(80H-FFH),具體可查看附錄中的(de)相(xiang)關表。sfr是(shi)定義8位的(de)特殊功能寄存器而sfr16則是(shi)用來定義16位特殊功能寄存器,如(ru)8052的(de)T2定時(shi)器,能定義為︰
    sfr16 T2 = 0xCC; //這里定義8052定時(shi)器2,地(di)址為T2L=CCH,T2H=CDH
用sfr16定義16位特殊功能寄存器時(shi),等號後面是(shi)它的(de)低(di)位地(di)址,高位地(di)址一定要位于物理低(di)位地(di)址之上。注意的(de)是(shi)不能用于定時(shi)器0和(he)1的(de)定義。
  sbit可定義可位尋址對(dui)象(xiang)。如(ru)訪問特殊功能寄存器中的(de)某位。其實這樣應(ying)用是(shi)經常要用的(de)如(ru)要訪問P1口中的(de)第2個(ge)引腳P1.1。我們能照以下(xia)的(de)方法(fa)去定義:
(1)sbit 位變量名=位地(di)址
  sbit P1_1 = Ox91;
這樣是(shi)把位的(de)絕對(dui)地(di)址賦給位變量。同sfr一樣sbit的(de)位地(di)址fan)匭胛揮0H-FFH之間。
(2)Sbit 位變量名=特殊功能寄存器名^位位置
sft P1 = 0x90;
  sbit P1_1 = P1 ^ 1; //先定義一個(ge)特殊功能寄存器名再(zai)指(zhi)定位變量名所在的(de)位置
當可尋址位位于特殊功能寄存器中時(shi)可采用這種方法(fa)
(3)sbit 位變量名=字節(jie)地(di)址^位位置
  sbit P1_1 = 0x90 ^ 1;
  這種方法(fa)其實和(he)2是(shi)一樣的(de),只是(shi)把特殊功能寄存器的(de)位址直接(jie)用常數表示。
  在單片機c語言存儲器類型中供(gong)給有一個(ge)bdata的(de)存儲器類型,這個(ge)是(shi)指(zhi)可位尋址的(de)數據存儲器,位于單片機的(de)可位尋址區中,能將要求可位錄址的(de)數據定義為bdata,如(ru):
unsigned char bdata ib; //在可位錄址區定義ucsigned char類型的(de)變量ib
int bdata ab[2]; //在可位尋址區定義數組ab[2],這些也稱為可尋址位對(dui)象(xiang)
sbit ib7=ib^7 //用關鍵字sbit定義位變量來獨(du)立訪問可尋址位對(dui)象(xiang)的(de)其中一位
sbit ab12=ab[1]^12;
  操作符" "後面的(de)位位置的(de)最(zui)大值取決于指(zhi)定的(de)基址類型,char0-7,int0-15,long0-31。
下(xia)面我們用上一課(ke)的(de)電路來實踐一下(xia)這一課(ke)的(de)知(zhi)識。同樣是(shi)做一下(xia)簡(jian)單的(de)跑(pao)馬燈(deng)實驗,項(xiang)目名為RunLED2。程(cheng)序如(ru)下(xia):

sfr P1 = 0x90; //這里沒有使用預定義文件,
sbit P1_0 = P1 ^ 0; //而是(shi)自(zi)己定義特殊寄存器
sbit P1_7 = 0x90 ^ 7; //之前我們使用的(de)預定義文件其實就是(shi)這個(ge)作用
sbit P1_1 = 0x91; //這里分別定義P1端口和(he)P10,P11,P17引腳

void main(void)
{
unsigned int a;
unsigned char b;
do{
for (a=0;a<50000;a++)
P1_0 = 0; //點亮P1_0
for (a=0;a<50000;a++)
P1_7 = 0; //點亮P1_7
for (b=0;b<255;b++)
{
for (a=0;a<10000;a++)
P1 = b; //用b的(de)值來做跑(pao)馬燈(deng)的(de)花樣
}
P1 = 255; //熄滅P1上的(de)LED
for (b=0;b<255;b++)
{
for (a=0;a<10000;a++) //P1_1閃(shan)爍
P1_1 = 0;
for (a=0;a<10000;a++)
P1_1 = 1;
}
}while(1);
}

 

. Keil c51指(zhi)針變量
單片機c語言支持(chi)一般指(zhi)針(Generic Pointer)和(he)存儲器指(zhi)針(Memory_Specific Pointer).
1. 1. 一般指(zhi)針
一般指(zhi)針的(de)聲明和(he)使用均與標準C相(xiang)同,不過同時(shi)還能說明指(zhi)針的(de)存儲類型,例(li)如(ru)︰
long * state;為一個(ge)指(zhi)向long型整數的(de)指(zhi)針,而state本身(shen)則依(yi)存儲模式存放。
char * xdata ptr;ptr為一個(ge)指(zhi)向char數據的(de)指(zhi)針,而ptr本身(shen)放于外部RAM區,以上的(de)long,char等指(zhi)針指(zhi)向的(de)數據可存放于任何存儲器中。
一般指(zhi)針本身(shen)用3個(ge)字節(jie)存放,分別為存儲器類型,高位偏移,低(di)位偏移量。
2. 2. 存儲器指(zhi)針
基于存儲器的(de)指(zhi)針說明時(shi)即指(zhi)定了存貯類型,例(li)如(ru)︰
char data * str;str指(zhi)向data區中char型數據
int xdata * pow; pow指(zhi)向外部RAM的(de)int型整數。
這種指(zhi)針存放時(shi),只需一個(ge)字節(jie)或(huo)2個(ge)字節(jie)就夠(gou)了,因為只需存放偏移量。
3. 3. 指(zhi)針轉換
即指(zhi)針在上兩種類型之間轉化︰
l 當基于存儲器的(de)指(zhi)針作為一個(ge)實參傳(chuan)遞給需要一般指(zhi)針的(de)函數時(shi),指(zhi)針自(zi)動轉化。
l 如(ru)果不說明外部函數原形,基于存儲器的(de)指(zhi)針自(zi)動轉化為一般指(zhi)針,導致錯誤,因而請用“#include”說明所有函數原形。
l 能強(qiang)行改(gai)變指(zhi)針類型。

 變量的(de)存儲類別

一、static(靜態局部)變量。
1、靜態局部變量在程(cheng)序整個(ge)運行期間都不會(hui)釋(shi)放內存。
2、對(dui)于靜態局部變量,是(shi)在編譯的(de)時(shi)候賦初值的(de),即只賦chi)狄淮巍Hru)果在程(cheng)序運行時(shi)已經有初值,則以後每次調用的(de)時(shi)候不再(zai)重新(xin)賦chi)怠br />3、如(ru)果定義局部變量的(de)時(shi)候不賦chi)擔 蟣嘁氳de)時(shi)候自(zi)動賦chi)滴。而對(dui)于自(zi)動變量而言,定義的(de)時(shi)候不賦chi)擔 蚴shi)一個(ge)不確定的(de)值。
4、雖然靜態變量在函數調用結(jie)束(shu)後仍(reng)然存在,但是(shi)其他函數不能引用。
 
  二、用extern聲明外部變量。
用extern聲明外部變量,是(shi)為了擴(kuo)展外部變量的(de)作用範圍。比(bi)如(ru)一個(ge)程(cheng)序能由多個(ge)源程(cheng)序文件組成。如(ru)果一個(ge)程(cheng)序中需要引用另(ling)外一個(ge)文件中已經定義的(de)外部變量,就需要使用extern來聲明。
  正(zheng)確的(de)做法(fa)是(shi)在一個(ge)文件中定義外部變量,而在另(ling)外一個(ge)文件中使用extern對(dui)該變量作外部變量聲明。
  一個(ge)文件中︰   int abc;
  另(ling)外一個(ge)文件中︰   extern abc;
 
例(li)子︰
用extern將外部變量的(de)作用域擴(kuo)展到其他文件︰
文件1︰
//用extern將外部變量的(de)作用域擴(kuo)展到其他文件中
#include
#include
#include
unsigned int array[10];
void fillarray();
void init_ser()
{
 SCON=0X50;
 TMOD=0X20;
 TH1=0XF3;
 TR1=1;
 TI=1;
}
void main()
{
 unsigned int i;
 init_ser();
 fillarray();
 for(i=0;i<10;i++)
 {
  printf("array[%d]=%d\n",i,array[i]);
 }
  for(;;){;}
}
 
文件2︰
extern int array[10];
void fillarray()
{
 unsigned char i;
 for(i=0;i<10;i++)
 {
  array[i]=i;
 }
}

 

在單片機c語言中變量的(de)空(kong)間分配(pei)幾個(ge)方法(fa)

1、 data區空(kong)間小,所以只有頻繁(fan)用到或(huo)對(dui)運算(suan)速度(du)要求很高的(de)變量才放到data區內,比(bi)如(ru)for循環中的(de)計(ji)數值。

2、 data區內最(zui)好放局部變量。

因為局部變量的(de)空(kong)間是(shi)能覆(fu)蓋的(de)某個(ge)函數的(de)局部變量空(kong)間在退出該函數是(shi)就釋(shi)放,由別的(de)函數的(de)局部變量覆(fu)蓋),能提高內存利(li)用率(lv)。當bi)瘓蔡 植勘淞砍chu)外,其內存使用方式jie)肴 直淞肯xiang)同;

3、 確fan)D愕de)程(cheng)序中沒有未調用的(de)函數。

在Keil C里遇(yu)到未調用函數,編譯器就將其認為可能是(shi)中斷函數。函數里用的(de)局部變量的(de)空(kong)間是(shi)不釋(shi)放,也就是(shi)同全局變量一樣處理。這一點Keil C做得很愚蠢,但也沒辦法(fa)。

4、 程(cheng)序中遇(yu)到的(de)邏輯標志變量能定義到bdata中,能大大降低(di)內存佔用空(kong)間。

在51系列芯片中有16個(ge)字節(jie)位尋址區bdata,其中能定義8*16=128個(ge)邏輯變量。定義方法(fa)是(shi)︰ bdata bit LedState;但位類型不能用在數組和(he)結(jie)構體中。

5、 其他不頻繁(fan)用到和(he)對(dui)運算(suan)速度(du)要求不高的(de)變量都放到xdata區。

6、 如(ru)果想節(jie)省data空(kong)間就必須用large模式,將未定義內存位置的(de)變量全放到xdata區。當bi)蛔zui)好對(dui)所有變量都要指(zhi)定內存類型。

7、 當使用到指(zhi)針時(shi),要指(zhi)定指(zhi)針指(zhi)向的(de)內存類型。

在單片機c51語言中未定義指(zhi)向內存類型的(de)通(tong)用指(zhi)針佔用3個(ge)字節(jie);而指(zhi)定指(zhi)向data區的(de)指(zhi)針只佔1個(ge)字節(jie);指(zhi)定指(zhi)向xdata區的(de)指(zhi)針佔2個(ge)字節(jie)。如(ru)指(zhi)針p是(shi)指(zhi)向data區,則應(ying)定義為︰ char data *p;。還可指(zhi)定指(zhi)針本身(shen)的(de)存放內存類型,如(ru)︰char data * xdata p;。其含(han)義是(shi)指(zhi)針p指(zhi)向data區變量,而其本身(shen)存放在xdata區。

發表評論】【告訴好友】【收藏此文】【關閉(bi)窗口

网上彩票代理官网

网上彩票代理官网

网上彩票代理官网 | 下一页