Ⅰ 關於單片機存儲器的問題,idata,data,badata,xdata,pdata,code,片內存儲區,片外存儲區都是些什麼關系啊
關於51單片機內存問題,一直是個疑惑大家的問題,因為51單片機是個很另類的單片機。
下面我給樓主講解一下:
51單片機之所以另類,是因為,他定址內存的空間,不是靠匯流排,是用指令的方式。
51單片機有以下幾個內存模塊組成:
1】ROM或者Flash,叫程序存儲區,你寫的程序是存在這裡面的,上電後從這裡面執行。
程序存儲區也分為片內和片外,一般來說,現在的51很多已經做到了64K,所以很少有外擴
片外Flash或者片外的Rom了,Flash或者Rom不管是片內還是片外的,只能用來定義常量,是用code來修飾,也就是說,用code來修飾的東西,在程序運行過程中,不能修改;
2】RAM有------內部RAM的低128位(00-7F),對應C語言就是data,比如我定義一個變數,
data unsigned char Var = 0;
那麼,這個 Var變數就是放在內部的低128位Ram中
-------內部RAM的高128位(80-FF),對應C語言就是idata,比如我定義一個變數,
idata unsigned char Var = 0;
那麼,這個 Var變數就是放在內部的高128位Ram中
-------特殊功能寄存器(SFR)(80-FF),對應C語言就是Sfr比如我定義一個變數,
Sfr unsigned char Var = 0x90;
那麼,這個 Var變數就是放在內部的特殊功能寄存器中,這是你對Var操作,相當於操作一個特殊的寄存器,但是小心,不能隨便定義Sfr變數,很危險
------外部RAM 64K(0000-FFFF)
外部的RAM可以擴展到65536個,但是前256個算是一頁,這一頁比較特殊,是用
pdata來修飾的,當然,也可以用xdata來修飾。
除了第一頁的256個以外的其他65280個空間,只能用xdata來修飾;
回過頭來討論pdata和xdata,這兩個都能修飾外部Ram的第一頁,但是,Pdata只能修飾第一頁,即最前面的256個外部Ram,那麼,這最前面的256個到底用Pdata還是Xdata好的呢?
答案是Pdata,因為Xdata修飾的變數,用的是DPTR定址,Pdata用的是R0和R1.DPTR因為是16位的,所以可以覆蓋整個的64K外部Ram,R0和R1是8位,所以只能定址最前面的256個,也就是外部Ram的第一頁,但是,用R0定址,比DPTR快一倍,代碼也小的很多
樓主又疑惑了,好多地址是重復的,比如,我向80H地址寫一個數值,單片機怎麼知道讀的是內部的高128位RAM?還是SFR?還是外部64K的RAM呢?
答案是用指令,如果是直接定址,那麼訪問的就是SFR,如果是R0或者R1間接定址,就是內部高128位RAM,如果是DPTR或者是R0,R1間接定址,且配合的是MovX指令,那麼就是訪問外部64KRAM中的第80H個地址。
概括一下來說,51的內存由以下組成:
1----程序存儲器(包括片內Flash或Rom,也包括片外Flash或Rom,C語言用Code定義)
2----內部低128位Ram,C語言用data定義
3---內部高128位Ram,C語言用idata定義
4---內部SFR,C語言用Sfr定義
5---外部65536個Ram(通常,很多單片機廠家不會給你擴展那麼多的,一般來說擴展256個位元組或者1024個位元組就差不多了,最近宏晶的出了個擴展4096位元組的。這65536位元組的Ram,前256個可以用Pdata修飾,也可以用Xdata修飾,超過256個之後的,只能用Xdata修飾)
以上所說的只是針對51內核的單片機,其他內核的,像ARM之類的,不是這種結構的。
最後,回答樓主的問題:
片外存儲區是什麼?
這個問題太模糊,答案可以是外擴的Flash,也可以說是外擴的RAM,
如果問題是這么問的:
程序或者常量存儲在片外存儲區,這個片外存儲區指的是什麼?
答案是外擴Flash;
如果問題是---變數存儲在片外存儲區,這個片外存儲區指的是什麼?
答案是外擴RAM;
一般來說,如果不指明的話,外內存儲區,行業內人士指的是外部的Ram。
片內存儲器是什麼?是不是就是內部的E2PROM?
片內存儲區一般來說,指的是內部的Ram,包括高128位(idata)和低128位(data)
片內存儲器,這個說法我沒聽說過,可能是EEPROM吧。
Ⅱ Keil中data和idata,pdata,xdata以及code的區別
使用軟體之前,要養成閱讀軟體幫助的良好習慣,而不是到處東問西問!
Cx51的存儲類型:Cx51通過以下的關鍵字定義了不同的存儲類型,從而確保能夠訪問到51架構的全部存儲空間。
code:訪問程序存儲器(默認僅限於標准51能夠定址的64kB空間內),生成的代碼主要通過 MOVC @A+DPTR實現。
data:訪問可直接定址的片內存儲器(標准51的低128位元組),從而實現對變數最高速的訪問。
idata:訪問間接定址的片內存儲器(標准51的256位元組)。
bdata:訪問位定址的片內存儲器(標准51中從20H開始的16位元組),支持位+位元組的混合訪問模式。
xdata:訪問外部數據存儲器(默認僅限於標准51能夠定址的64kB空間內),生成的代碼主要通過MOVX @A+DPTR實現。
far:擴展的RAM及ROM訪問方式,最大支持16MB定址空間,至於生成的代碼方式則取決於用戶自定義的訪問程序或特定的晶元類型(例如恩智浦的80C51MX、Dallas390等)。
pdata:訪問當前頁面內的外部數據存儲器(256位元組),生成的代碼主要通過MOVX @Ri實現。
Ⅲ STC89C52,51增強型單片機內部資源問題
關於STC89C52:
1、STC89C52隻有512位元組的的RAM,包括2部份,一是256位元組的內部RAM,二是256位元組的外部RAM;STC89C54以上的晶元才有1K的RAM(內256+外1024)。
2、1K的EEPROM(應為2K)出廠時內置有支持串列下載功能的代碼,配合官方下載軟體完成代碼的串口下載。這個區域在實際應用當中也可用於可保存斷電後不能丟失的數據,但實際操作上不能像RAM那樣直接讀寫,需要通過專門的寄存器操作來完成讀寫。
3、EEPROM不是ROM,也不是RAM,EEPROM也沒有用作RAM--你先這樣記,這個問題說起來內容比較多,後面細談。
4、Flash程序存儲器8K就是當ROM用(這句話嚴格的講應該說成「Flash程序存儲器8K就是當程序存儲器用」):基本上是這樣。關於ROM、FALSH後面細說。
是否需要1K的RAM:可在編譯完成後觀察編譯結果,如果能編譯成功,應該有類似下面的信息:「program size:data=9.0,xdata=1,code =2345」,其中data的整數部份就是你實際需要的內部RAM位元組數,xdata是你實際需要的外部RAM位元組數,code是代碼長度。你可以根據這個信息選擇最合適的STC單片機型號。具體到STC89C52:data<256,xdata<256,code<8192就行
對上述的一些概念補充說明(包括_at_)
1、51單片機的C語言中有個需要關注的概念就是變數或數據的存儲模式(PC機是否有類似的情況我不了解)。在C51中的存儲模式是data、bdata、idata、pdata、xdata、code共6種:
data、bdata、idata:就是說變數或數據位於單片機的內部RAM中(ST89C52有256位元組),訪問速度最快。
pdata、xdata:就是說變數或數據位於擴展的外部RAM中(ST89C52內集成了256位元組),相對內部RAM訪問速度要慢。
code:就是程序代碼,位於單片機的程序存儲其中(ST89C52內含8192位元組)
KEIL C編譯時在有個選項叫數據存儲模式(Memory Model),如果選擇小模式,則程序中的變數一般會放在內部RAM(data)中,選擇其它模式則會放在外部RAM(xdata或pdata,採用這兩種存儲模式的變數在物理上都放在外部RAM中,只是定址方式有所不同,整體上pdata更快些);當然,如果在定義變數時就聲明了存儲模式,編譯時會根據聲明決定該變數在哪個區。比如:char data flag就是指定將flag放在內部RAM中;char xdata flag _at_0x0000則指定放在外部RAM中,而且地址是0x0000。
"_at_" 用於指定變數在內存中的地址。指定地址的方法優點在於調試方便,比如模擬單步運行時可以直接到該地址去更直觀的觀察變數的實際變化情況,若不指定則編譯器會自己決定放在什麼地方,只能通過.M51文件去獲取該變數的地址了。其缺點則是容易出錯,由於人為的因素,可能會成各變數的地址重疊。所以實際應用中一般都不指定地址,編譯器會自動安排的,除非是特殊要求。
這里針對內部RAM和外部RAM再說幾句:早先的單片機(8031、8032)外部RAM和程序存儲器都需要通過P0口P2口來擴展的,51單片機本身沒有哪怕是1個位元組的外部RAM,擴展起來很麻煩。後來隨著發展才演變到現在幾乎所有的單片機都或多或少的集成了RAM和程序存儲器,這樣大多數應用只需要設計功能電路就可以了,不需要再去擴展,這就降低了不少成本。
2、關於FLASH、ROM、PROM、EPROM、EEPROM、RAM
我們現在一般都會把單片機的程序存儲器叫ROM,早先的硬體程序代碼確實是放在ROM型的器件中(包括電腦的BIOS),所以ROM就是程序、程序就是ROM,大家都理解,就成習慣了。其實這是不對的,真正的ROM現在很少用了。下面就這幾個名詞解釋一下:
RAM:一般都叫內存,特點是讀寫速度快,但斷電後數據丟失(後5種斷電後數據不丟失)
ROM:只讀存儲器。特點是只能讀,其內容在晶元出廠時就已經固化,如果有錯只能扔掉
PROM:可編程只讀存儲器。特點是實際應用中只能讀,但應用產品生產環節可由用戶來完成對晶元的編程,只能寫1次,有錯的話下場同ROM。
EPROM:可重復擦寫的只讀存儲器。特點是實際應用中只能讀,但可以通過紫外線擦除(也有電擦除的),從而實現再編程,只是編程時一般需要將晶元取下來在專用設備上擦除、編程(電擦除的雖然可以在用戶系統上實現擦除及編程,但必須設計專門的擦除編程電路)。上世紀90年代基本上都採用的是這種模式,如果你看到某個晶元上有個小玻璃窗,一般就是這種工藝的晶元。紫外線擦除需要15分鍾的時間,也很麻煩,而且映像中編程次數只有1000次。
EEPROM:可重復擦寫的非易失性存儲器。特點是可讀可寫,且斷電後數據不丟失。採取這種工藝的晶元大多數都是通過IIC匯流排模式來訪問的。但其容量一般都不大,適合於數據不多的應用。
FLASH:可重復擦寫的非易失性存儲器。特點是可讀可寫,且斷電後數據不丟失。與EEPROM的主要區別在於口線更多、存儲容量更大、速度更快,還有就是擦寫方式不同:EEPROM可按位元組擦寫,而FLASH是塊擦寫模式,所以速度上FALSH的讀寫更快。
STC單片機為什麼要採取EEPROM的模式而不採用FLASH我不知道,可能是因為EEPROM相對成本較低,而且可以直接用作非易失性存儲,不需要用戶外擴EEPROM了。
Ⅳ 一個關於Keil C關鍵字xdata和data的問題
1.xdata表示這是一個外部RAM地址內的數據,數據最終將被保存至外部RAM的某個地址單元中;
但是,外部RAM只能通過寄存器間接定址來訪問,也就是說,其地址需要保存在內部RAM中(其實或許是SFR中,8位地址一般是R0、R1,16位地址一般通過DPTR間址)
這里,DPTR里保存的內容就相當於指向外部RAM單元的指針了…… 所以,用了內部數據類型(data)的指針,和外部數據類型(xdata)
2. 這里變數pAddress應該是指針型變數,所以給pAddress賦值應是外部地址, *pAddress才是在外部RAM地址的內容,因此它的數據類型是xdata(換句話說,pAddress是指針,*pAddress是指針指向的數據)
Ⅳ KEIL 編程 如何使用XDATA
如果是匯編,XDATA的很好訪問,直接用MOVX指令,訪問的就是XDATA,比如:
MOVDPTR,#1000H
MOVXA,@DPTR
如果是C語言,那麼聲明變數時加上xdata就可以了。比如
#include<reg51.h>
unsignedintxdataa;
main()
{
a=0x5a;
printf("%d",a);
while(1);
}
也可以採取另一種方式來訪問XDATA,比如:
#include<reg51.h>
#include<absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
//PA、PB、PC埠及命令埠地址定義
#definePAXBYTE[0x0000]
#definePBXBYTE[0x0001]
#definePCXBYTE[0x0002]
#defineCOMXBYTE[0x0003]
//待顯示字元編碼隊列
ucharcodeDSY_CODE_Queue[]={
0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xa4,0xc0,0xc0,0x80,0xc0,0x80,0xf9,
0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
//數碼管選通
ucharcodeDSY_Index[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//延時
voidDelayMS(uintms)
{
uchari;
while(ms--)for(i=0;i<120;i++);
}
//主程序
voidmain()
{
uinti,j,k;
COM=0x80;//8255工作方式選擇:PA、PB均輸出,工作方式0
while(1)
{
for(j=0;j<40;j++)//刷新顯示一段時間
{
for(k=0;k<8;k++)//在8個數碼管上顯示字元
{
PB=DSY_Index[k];//位碼
PA=DSY_CODE_Queue[k+1];//段碼
DelayMS(1);
}
}
i=(i+1)%15;//刷新顯示一段時間後遞增i,形成滾動效果,最大索引為14
}
}
Ⅵ 51單片機定義一個大數組存在idata與xdata中有什麼區別
51單片機定義一個大數組存在idata與xdata區別為:空間不同、訪問不同、獲取不同。
一、空間不同
1、idata:idata佔用51單片機內部RAM的固定0x00-0xff空間。
2、xdata:xdata佔用51單片機外部RAM擴展的0x0000-0xffff空間。
二、訪問不同
1、idata:idata用類似C中的指針方式進行訪問。
2、xdata:xdata用DPTR進行訪問。
三、獲取不同
1、idata:51單片機編譯成功後,在idata區中,可以直接獲取到定義的數組。
2、xdata:51單片機編譯成功後,在xdata區中,不可以直接獲取到定義的數組。
Ⅶ 關於單片機內存問題,DATA和XDATA具體是怎麼樣的
選擇small 模式你定義的變數默認為data模式,即變數存放與單片機的內部ram,而large模式下,定義的變數存放於外部ram。前者運算速度快於後者。
Ⅷ 單片機 keil編程中我把data數據改成xdata類型,編譯無誤,但程序運行不了!為什麼急!
編譯肯定不會報錯,你改xdata只不過C編譯器編譯成MOVX @DPTR這樣的指令,如果沒有外擴存儲器,可定跑不起來。而且我有一點疑問的是你把data用了接近128 Bytes,你主函數定義的變數很多還是用了iteration?
我懷疑你是不是data空間裡面你是不是很多的constant,constant建議放在內部FLASH中,使用movc @dptr查表。
可以用pdata申明變數,用mov @Ri間接定址方式訪問內部全部的256bytes空間!
Ⅸ 關於keil中的data和xdata 問題
「我用的單片機有512位元組的空間」
即使有額外的SRAM,一般也需要設置寄存器打開的。而且只擴256位元組的型號一般映射到頁內空間,需通過MOVX與@Ri訪問。所以你可以試試PDATA方式。
「我的程序中的變數超過114位元組就編譯不通過了」
應當將部分變數分配到內部間接定址區,如下:
unsigned char idata ucMyVariable;