2016-04-09 6 views
1

私は8ビットのレジスタを持っています。他のビットを変更せずにビット4,5,6を変更したいと思います。 これらのビットは、000から111までの値を取ることができます(以前の状態に関係なく)。 ワンステップで変更する方法はありますか、それとも個別に変更する必要がありますか?レジスタ内の複数のビットを変更する

答えて

1

あなたは0である、既知の状態で要求されたビットを置くためにマスクを必要とします私たちは、変更することが0にビットを設定する反転マスクを使用

#define mask 0x70 // 01110000b bit 4, 5 & 6 set 
reg = (reg & ~mask) | (newVal & mask); 

をし、そのままマスクに:私のプログラミングの習慣ごとなど、より便利に、そしてあなたがまたは操作を1にしたいとライトバックビットを設定私たちがしたくないビットを0に設定する新しい価値を妨げる
新しい価値の不要なビットは常にあなたが簡素化することができます0であることを確認している場合:

#define mask 0x8f // 10001111b bit 4, 5 & 6 reset 
reg = (reg & mask) | newVal; //newVal must have always bits 7, 3, 2, 1 & 0 reset. 
+0

既知の状態では '0'が' 1'よりどのように便利であるかわかりません。次のステップで、あなたが望むビットを( '|'演算で)オンにするか、オフにするビットをオフにするか( '&'演算で)のどちらかの問題です。 –

+0

@ JohnBollinger、私はあなたが言ったように、必要なビットをセットするために値の間に値が必要なので、より便利であると考えます。それらをリセットするには、レジスタ値を反転させる必要があります。入力値。 2つの操作が必要です。 –

+0

いいえ、代替案はあなたの例とまったく同じくらい複雑で、入力を反転する必要はありません: 'reg =(reg | mask)&(newVal |〜mask)'。 –

1

あなたは、ビットごとの操作によってそれを行うすなわち最初の3ビットをクリアし、それらを設定することができます。

unsigned char value = 0x70; 
unsigned char r = 0xFF; 
r = (r & 0x8F) | value; 
+0

ビット単位または '|'を意味すると思いますか? – Unimportant

+0

ああ、確かに、はい、固定、ありがとう@ user1320881 – fluter

1

あなたは、構造体の内側bit-fieldを使用することができます。

typedef struct{ 
    unsigned char b0_3 : 4; 
    unsigned char b4_6 : 3; 
    unsigned char b7 : 1; 
}your_reg_type; 

your_reg_type my_register; 

//modify only the bits you need 
my_register.b4_6 = 0x02; 

は、あなたのコンパイラが注文する方法をご覧ください構造体内のビットを試してみてください。order your bit-field accordingly

+0

この回答はCで保証されていないので、最初のビットはビット7です。ビット0でもかまいません。 – user3629249

+0

だから私は "ターゲットのエンドエンティティをチェックアウトしました..." – simpego81

+0

1バイトの場合、それはエンディアンの問題ではなく、むしろコンパイラの実装です。実際にはマルチバイトの場合でもエンディアンの問題ではありません。エンディアンはバイトオーダーではなくバイトオーダーに関するものです。コンパイラは、バイト順序にかかわらずMSBまたはLSBからビットをパックすることがあります。ですから、ターゲットのエンディアンではなくコンパイラのドキュメントをチェックしてください。これは、同じターゲットの異なるコンパイラ間で変更される可能性があることに注意してください。 – Clifford

0

3つの連続したビットの値が意味を持つ場合(つまり、すでに提案されています) 。例えば、独立したフラグまたは制御ビットの集合ではなく、0から7の値である)、値内のビット位置の詳細を直接符号化するのではなく、単純な数値範囲0〜7としてその値を保持すると便利です。その場合には:もちろん

 assert(val <= 7) ; // During debug (when NDEBUG not defined) the 
          // assert trap will catch out-of-range inputs 

    reg = (reg & mask) | (val << 4) ; 

あり(シフト動作を追加することによって)このようにインターフェイスを簡略化するために支払うためにいくつかの小さなコストであるが、利点は、レジスタ・フィールドレイアウトの詳細についての知識があることです1か所に制限されています。

関連する問題