有注册表的地址(第一个?)SPI1。 有结构有偏移。我想这意味着 SPI1_REG_BASE + offset =某些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;
有一些定义和指针* 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?
但是为什么SPIDAT1注册表的CSHOLD字段的地址为0x10000000?
spi->SPIDAT1 |= CSHOLD //set bit 28
SPIDAT1寄存器的偏移地址为3Ch(0x01F0E000 + 0x3C) 它确实有字段CSHOLD(第28位)
如何| =在这种情况下工作?
我会感激任何帮助找出......所有这些%)
答案 0 :(得分: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位,将所有其他位保留为其原始值。
答案 1 :(得分:1)
但是为什么CSDEF0是0位?
因为:
#define CSDEF0 (0x00000001) //bit 0
他们的意思不是“有0位的位”而是“0位的位”。
关于:
#define CSHOLD(0x10000000)//第28位
看看将hex-notation转换为二进制表示法,它将变得清晰。
如何| =在这种情况下工作?
1位 AT 这些位置(0和28)或'成为该变量之前的值。
答案 2 :(得分:1)
但为什么CSDEF0是0位
该宏的目的是将bit-0设置为1.如果该宏与任何寄存器进行“或”运算,则该寄存器的bit-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位。
我猜你混淆了Hexa-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
答案 3 :(得分: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 + offset)内访问。