我想直接使用它的物理地址来操作寄存器的一些位。但是我找不到办法做到这一点。我看到了一些关于设置位掩码的帖子,但我觉得它们太混乱了。
我的寄存器物理地址是:0x4A10005C
我想操纵它在 18-16 位之间的位。我想0x3
在这些位中设置。
如果你们能提供答案或方法,我将非常高兴。谢谢。
我想直接使用它的物理地址来操作寄存器的一些位。但是我找不到办法做到这一点。我看到了一些关于设置位掩码的帖子,但我觉得它们太混乱了。
我的寄存器物理地址是:0x4A10005C
我想操纵它在 18-16 位之间的位。我想0x3
在这些位中设置。
如果你们能提供答案或方法,我将非常高兴。谢谢。
您可以只定义一个指向寄存器的指针,然后使用正常的 C 位操作来操作各个位:
volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C;
// set up a pointer to the register
uint32_t val = *my_register; // read register
val &= ~(0x7 << 16); // clear bits 16..18
val |= (0x3 << 16); // set bits 16..18 to 0x03 (i.e. set bits 16 and 17)
*my_register = val; // write register
(以上假设您正在讨论寄存器中的三位,即第 16、17 和 18 位,并且您希望将第 18 位设置为零,将第 16 位和第 17 位设置为 1。)
位掩码很容易理解,所以让我们先来看看:
假设您的 32 位寄存器现在包含一些值,我将任意选择 0xF48C6219 16
我假设您知道如何将十六进制转换为二进制,如果不知道的话......让我们说使用计算器或谷歌(而不是深入了解其中的细节)。所以我们的十六进制值可以用二进制表示为:
+-- bit 31 +-- bit 0
| |
v v
1111 0100 1000 1100 0110 0010 0001 1001
^ ^
| |
+-+-- bits you want to set, 16-18
布尔逻辑告诉我们:
1) 任何 OR'd ( |
)1
都会给你一个值1
。或“设置”位。
2) 任何 AND'd ( &
)0
都会给你一个值0
。或“清除”该位。
因此,如果我们想清除第 16-18 位,您可以使用如下掩码进行 AND 操作:
基数:1111 0100 1000 1100 0110 0010 0001 1001 2 == 0xF48C6219 16
掩码数:1111 1111 1111 1000 1111 1111 1111 1111 2 == 0xFFF8FFF 16
1111 0100 1000 1100 0110 0010 0001 1001
& 1111 1111 1111 1000 1111 1111 1111 1111
------------------------------------------
1111 0100 1000 1000 0110 0010 0001 1001
现在你可以用你想在那里设置的任何东西来或它:
新掩码号:0000 0000 0000 0011 0000 0000 0000 0000 2 == 0x00030000 16
1111 0100 1000 1000 0110 0010 0001 1001
| 0000 0000 0000 0011 0000 0000 0000 0000
-----------------------------------------
1111 0100 1000 1011 0110 0010 0001 1001
所以在代码中:
#define CLEAR_MASK 0x70000 //70000 is shorter to write, so just do this and flip it
#define SET_3_MASK 0x30000
volatile uint32_t * const reg = (uint32_t *) 0x4A10005C;//set a pointer to the register
*reg &= ~CLEAR_MASK; //~ filps the bits
*reg |= SET_3_MASK;
您可以使用移位等技巧来做一些技巧,但这是位掩码的基础知识以及它们的工作原理。希望能帮助到你。
structure r32 {
unsigned int bit0 :1;
unsigned int bit1 :1;
unsigned int bit2 :1;
unsigned int bit3 :1;
unsigned int bit4 :1;
unsigned int bit5 :1;
.
.
.
unsigned int bit31 :1;
}
在你的主要
structure r32 *p;
volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C;
p = (structure r32 *) my_register;
然后例如访问第 5 位
p->bit4 = 0;