最近都是翻舊案子,是以不太忙,花時間把以前的問題做下回顧,不懂的地方做下實驗,關于xdata做下記錄吧!
1.code裡關于xdata的了解
在code裡,經常看到這樣的寫法(scRegs[(u16Addr)&0xFF]),如圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLzcjM1UjMwIjMyEjNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
現在就scRegs這個寫法做下分析:
xdata是large存儲類型,volatile是通過硬體來改變指針指向的内容。
如:#define scRegs ((unsigned char volatile xdata ) 0x2F00)
說明:定義 msRegs為指向xdata位址空間unsigned char資料類型指針(注意是指針!!),指針值為0x2F00。這樣就可以直接用scRegs[Addr]或(scRegs+Addr)通路外部RAM了。至于 volatile的作用就是讓編譯器不至于優化掉它的操作,但是scRegs[Addr]的具體内容就要看0x2F00+Addr這個寄存器的位置裡放的内容,這個要查晶片手冊了。
eg.如:MEM_SCREAD_BYTE(SC0_CE)的解釋
原型為:#define MEM_SCREAD_BYTE(u16Addr) (scRegs[(u16Addr)&0xFF]),
已知:#define scRegs ((unsigned char volatile xdata *) 0x2F00)
那麼轉換過來就是(scRegs[0x00CE|_BIT15)&0xFF, 結果就是指向Scaler Bank的2F Bank,0xCE這個寄存器,即2FCEh這個位置,按位&上0xFF是取這個寄存器裡的内容。
是以MEM_SCREAD_BYTE(SC0_CE)的具體位置在晶片手冊裡就是Bank=2F,Sub-bank=00,即2FCE這個寄存器的位置。其在晶片手冊中位置如下圖(TSUMU588DG晶片):
****總結:使用XBYTE時,初始化方法是XBYTE[0xXXXX],這是C51中專有的東西,在C51程式設計中隻要有外部擴充RAM就得這樣用。在51單片機中,RAM空間有内外之分,而内部RAM與外部256位元組的RAM同位址,在有擴充外部RAM的系統中,有的會用上外部RAM的前256位元組,有的前256位元組沒有用。#define scRegs ((unsigned char volatile xdata *) 0x2F00)這個定義就是用後256位元組,即外部RAM從0x2F00開始尋址。
//8051 特有的記憶體型态
code 以 MOVC @A+DPTR 讀取的程式記憶體
data 可以直接存取的内部資料存儲器
idata 以 Mov @Rn 存取的内部資料存儲器
bdata 可以位尋址(Bit Addressable)的内部存儲器
xdata 以 MOVX @DPTR 存取的外部資料存儲器
pdata 以 MOVX @Rn 存取的外部資料存儲器
PS:另外關于xdata的具體了解,可參考這偏部落格,這篇部落格也對我的了解起了很大作用,感謝部落客的分享!
2.MStar晶片怎樣看寄存器
比如看SC0_E4這個寄存器:SCO代表scaleBank,0x00E4中,00代表Bank0,E4代表Bank0的E4這個寄存器,是以綜合起來就是0x00E4代表的是,scaleBank的Sub_Bank0的E4寄存器。
對應IC手冊位置:
使用MStar Monitor System Tool工具找對應的位置
3.向寄存器寫一位(bit)
有時候我們需要操作寄存器的某一個bit位,可以用這種方式:
void WriteBit( WORD u16Reg, Bool bBit, BYTE u8BitPos )
{
BYTE u8Value;
u8Value = ReadByte( u16Reg );
if( bBit )
{
u8Value = u8Value | u8BitPos;
}
else
{
u8Value = u8Value & ( ~u8BitPos );
}
WriteByte( u16Reg, u8Value );
}
//用法
WriteBit(REG_2E69, TRUE, _BIT4); //向REG_2E69這個寄存器的BIT4寫1
先讀出該寄存器存放在u8Value這個變量裡,然後判斷bBit,即寫入的是0還是1,是1的話,通過按位與運算,将指定位(u8BitPos)給1;
寫入的是0的話,先将指定位(u8BitPos)按位取反就将指定位清0了,進而不會影響其他位,然後按位與(&),這樣就将指定位清0.