レジスタの一部のビットを、その物理アドレスを使用して直接操作したいと思います。しかし、私はこれを作る方法を見つけることができませんでした。ビットマスクの設定に関する投稿をいくつか見ましたが、混乱しすぎています。
私のレジスタの物理アドレスは次のとおりです。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
(上記は、レジスタ内の3ビット、ビット16、17、および18について話していること、およびビット18をゼロに設定し、ビット16および17を1に設定することを前提としています。)
ビットマスクは非常に理解しやすいので、最初にそれを実行してみましょう。
32ビットレジスタに現在何らかの値が含まれているとしましょう。0xF48C621916を任意に選択します。
16進数を2進数に変換する方法を知っていると思いますが、そうでない場合は...電卓またはグーグルを使用するとしましょう(その核心に入るのではなく)。したがって、16進値は2進数で次のように表すことができます。
+-- 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(&
)を使用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
これで、そこに設定したいものとORすることができます。
新しいマスク番号: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;