天天看點

code裡關于xdata的一些了解及如何看寄存器

最近都是翻舊案子,是以不太忙,花時間把以前的問題做下回顧,不懂的地方做下實驗,關于xdata做下記錄吧!

1.code裡關于xdata的了解

在code裡,經常看到這樣的寫法(scRegs[(u16Addr)&0xFF]),如圖:

code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器

現在就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是取這個寄存器裡的内容。

code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器

是以MEM_SCREAD_BYTE(SC0_CE)的具體位置在晶片手冊裡就是Bank=2F,Sub-bank=00,即2FCE這個寄存器的位置。其在晶片手冊中位置如下圖(TSUMU588DG晶片):

code裡關于xdata的一些了解及如何看寄存器

****總結:使用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寄存器。

code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器

對應IC手冊位置:

code裡關于xdata的一些了解及如何看寄存器

使用MStar Monitor System Tool工具找對應的位置

code裡關于xdata的一些了解及如何看寄存器
code裡關于xdata的一些了解及如何看寄存器

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.

繼續閱讀