更改寄存器中的多个位
Changing more than one bit in a register
我有一个 8 位寄存器,我想在不改变其他位的情况下更改位 4,5 和 6。
这些位的值可以从 000
到 111
(不管它们之前的状态如何)。
有没有一种方法可以一步更改它们,或者我必须单独更改它们?
可以按位运算,即先清除3位,再置位:
unsigned char value = 0x70;
unsigned char r = 0xFF;
r = (r & 0x8F) | value;
你需要一个掩码来将请求的位置于已知状态,根据我的编程习惯,0 更方便,然后将你想要的位设置为 1一个或操作并回写:
#define mask 0x70 // 01110000b bit 4, 5 & 6 set
reg = (reg & ~mask) | (newVal & mask);
我们使用反向掩码将要更改的位设置为 0,使用未更改的掩码将我们不希望受到新值干扰的位设置为 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.
您可以在结构中使用 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;
之前,请检查您的编译器如何对结构内的位进行排序
许多解决方案和变体是可能的(并且已经被建议),但如果三个连续位的值本身有意义(即它是 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) ;
当然,以这种方式(通过添加移位操作)简化界面需要付出一些小成本,但优点是寄存器字段布局的细节知识仅限于一个地方。
我有一个 8 位寄存器,我想在不改变其他位的情况下更改位 4,5 和 6。
这些位的值可以从 000
到 111
(不管它们之前的状态如何)。
有没有一种方法可以一步更改它们,或者我必须单独更改它们?
可以按位运算,即先清除3位,再置位:
unsigned char value = 0x70;
unsigned char r = 0xFF;
r = (r & 0x8F) | value;
你需要一个掩码来将请求的位置于已知状态,根据我的编程习惯,0 更方便,然后将你想要的位设置为 1一个或操作并回写:
#define mask 0x70 // 01110000b bit 4, 5 & 6 set
reg = (reg & ~mask) | (newVal & mask);
我们使用反向掩码将要更改的位设置为 0,使用未更改的掩码将我们不希望受到新值干扰的位设置为 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.
您可以在结构中使用 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;
之前,请检查您的编译器如何对结构内的位进行排序
许多解决方案和变体是可能的(并且已经被建议),但如果三个连续位的值本身有意义(即它是 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) ;
当然,以这种方式(通过添加移位操作)简化界面需要付出一些小成本,但优点是寄存器字段布局的细节知识仅限于一个地方。