2013-02-07 60 views
1

有注册表地址(第一个?)SPI1。 有偏移的结构。我想这意味着一些SPI注册表如何设置寄存器中的位?

#define SPI1_REG_BASE   (0x01F0E000) 
//----------------------------------------------------- 
//Register Structure & Defines 
//----------------------------------------------------- 
typedef struct 
{ 
    volatile uint32_t SPIGCR0;  // 0x0000 
    volatile uint32_t SPIGCR1;  // 0x0004 
    volatile uint32_t SPIINT;   // 0x0008 
    volatile uint32_t SPILVL;   // 0x000C 
    volatile uint32_t SPIFLG;   // 0x0010 
    volatile uint32_t SPIPC0;   // 0x0014 
    volatile uint32_t SPIPC1;   // 0x0018 
    volatile uint32_t SPIPC2;   // 0x001C 
    volatile uint32_t SPIPC3;   // 0x0020 
    volatile uint32_t SPIPC4;   // 0x0024 
    volatile uint32_t SPIPC5;   // 0x0028 
    volatile uint32_t RSVD0[3];  // 0x002C 
    volatile uint32_t SPIDAT0;  // 0x0038 
    volatile uint32_t SPIDAT1;  // 0x003C 
    volatile uint32_t SPIBUF;   // 0x0040 
    volatile uint32_t SPIEMU;   // 0x0044 
    volatile uint32_t SPIDELAY;  // 0x0048 
    volatile uint32_t SPIDEF;   // 0x004C 
    volatile uint32_t SPIFMT0;  // 0x0050 
    volatile uint32_t SPIFMT1;  // 0x0054 
    volatile uint32_t SPIFMT2;  // 0x0058 
    volatile uint32_t SPIFMT3;  // 0x005C 
    volatile uint32_t INTVEC0;  // 0x0060 
    volatile uint32_t INTVEC1;  // 0x0064 
} spi_regs_t; 

的 SPI1_REG_BASE +偏移=地址有一些定义和指针* SPI的

#define CSDEF0 (0x00000001) //bit 0 
#define CSHOLD (0x10000000) //bit 28 
spi_regs_t *spi = (spi_regs_t *)SPI1_REG_BASE; 

我误解位的设置定义。例如,

spi->SPIDEF |= CSDEF0 //set 0 bit in the registry field 

我明白SPIDEF - 是SPI寄存器已偏移地址4CH
(0x01F0E000 + 0x4C)。但为什么CSDEF0位0? SPIDEF注册表中有一个字段CSDEF(0-7位)。是否意味着7位CSDEF的地址是0x00000008?和5位的地址是0x00000006?

但是为什么CSHOLD字段的SPIDAT1注册表的地址是0x10000000?

spi->SPIDAT1 |= CSHOLD //set bit 28 

SPIDAT1寄存器已经偏移地址CH(0x01F0E000 +为0x3C) 它确实有场CSHOLD(28st位)

如何|在这种情况下=工作?

我会任何帮助搞清楚......这一切%)

回答

1

但为什么CSDEF0位0?

该宏的目的是位0设置为1。如果该宏被进行或运算与任何寄存器,则该寄存器的位0设置为1。

例如

允许采取spi->SPIDEF = 0x050A我。È0x050A ==> 0000 0101 0000 1010

现在设定使用CSDEF0 SPI-> SPIDEF的第0位。

0x050A  ==> 0000 0101 0000 1010 
CSDEF0  ==> 0000 0000 0000 0001 
       -------------------- 

spi->SPIDEF ==> 0000 0101 0000 1011

为什么SPIDAT1注册表的CSHOLD领域具有0x10000000的地址?

同路CSDEF0是如何用来表示第0位,CSHOLD用于第28位。

我想你混淆六-deciamal和0x000001和000001(???)二进制表示。

0x01 is 01. 
0x02 is 10. 
0x100 is 1 0000 0000 
0x1000 is 1 0000 0000 0000 
0x10000000 is 1 0000 0000 0000 0000 0000 0000 0000 
       ^-- Bit 28 starting from bit-0 
+0

Jeyaram,谢谢你这么多详细的解释!CSDEF5 = 0×20(HEX )是0000 0000 0010 0000(BIN)的它代表的,SPI> SPIDEF值第5位?它是正确的吗? – Myosotis

+1

正确的。你可以使用CSDEF5到其它寄存器的第5位设置为1个太:) – Jeyaram

+0

理由downvote ?? – Jeyaram

1

感激但是为什么CSDEF0是位0?

因为:

#define CSDEF0 (0x00000001) //bit 0 

他们的意思是不是 “位值为0”,但 “在位置0位”。

以及有关:

的#define CSHOLD(0x10000000处)//位28

看看十六进制表示法转换为二进制记数法,它会变得清晰。

如何在此情况下工作?

的1位AT那些位置(0和28)是或运算成,这在以前在该变量的值。

+0

eznme,谢谢你的回答!我用十六进制转换CSHOLD。它是128.我仍然不知道如何确定29位的位地址? – Myosotis

+1

没有*位的地址*。要使用位29,可以使用位数为29的*整数*。这个整数是'(1u << 29)',又名'0x20000000'。你用'something | =(1u << 29)'来设置位29,'something&=〜(1u << 29)'来清除位29,并且'(某些东西&(1u <<29))>> 29'来检查位29 。 –

+1

@Myosotis 0x10000000的是b10000000000000000000000000000位在指标28值1 –

1

位没有单独的地址。

而是在嵌入式世界的普遍做法是连接几个小属性更大的寄存器。例如一个可以定义实时调度的一些内部为:

具有
31 30 29 28 27  26 25 24 32 22  21 20 19  18   0 
[ max_priority ] [ current_priority] [ reserved] [ address_xxxx ] 

这里MAX_PRIORITY将是5位无符号整数值0-31; 也可以定义max_priority0是该值的最低有效位。所有这些参数都将在相同的绝对地址(REG_BASE +偏移量)内访问。

4

我想你是误会了寄存器的地址和值的概念。

当你说SPI1模块的CSDEF0寄存器位于地址0x01F0E000 + 0x4C你是正确的(根据您所提供的结构说明)。这个地址永远不会改变,它由硬件设计来定义。

现在用下面的语句你是不是操纵地址,但值寄存器:

spi->SPIDEF |= CSDEF0; //set 0 bit in the registry field 
spi->SPIDAT1 |= CSHOLD; //set bit 28 

|=运算符是一个按位OR和赋值运算符。它等效于以下情况:

spi->SPIDEF = spi->SPIDEF | CSDEF0; //set 0 bit in the registry field 
spi->SPIDAT1 = spi->SPIDAT1 | CSHOLD; //set bit 28 

由于CSDEF0被定义为0x00000001,在第一条语句您可以有效地设置SPIDEF寄存器的LSB位,而所有其他位的原始值。

+0

greydet,谢谢!spi-> SPIDEF | = 0x00000002将设置存储在此注册表中的第1位值,因为0x00000002 - 在二进制视图中为10,所以我们设置了第1位。 – Myosotis