天天看点

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.

继续阅读