我正在查看微控制器驱动程序文件,并且无法理解正确使用联合和位字段
typedef union
{
uint8 U; //Unsigned
sint8 I; //signed
Register_x_Bits B; //Bit field access
}u1;
typedef struct _Register_x_Bits //8 bit register size
{
uint8 Field1:1; //endianness is maintained for all registers
uint8 Field2:1;
uint8 Field3:1;
uint8 Field4:1;
uint8 Field5:4;
}Register_x_Bits;
u1 reg;
reg.U = ReadRegister(); // data is initially being read from the register
//based on the previous data a bit value needs to be changed in particular location of the data
reg.B.Field3 = 0;
WriteRegister(reg.U);
这是我无法理解的地方
1)通过仅改变reg.B.Field3
位字段值,它是否只改变一个特定位(在这种情况下为字段3)或者清除寄存器中的所有先前数据并用新的{{填充它1}}
许多教程都声明reg.B.Field3
2)我可以在同一个寄存器中更改多个位字段吗? 我可以通过上述相同的方法更改它们并保持其余完整
Unions
让整个寄存器值为reg.B.Field1 =0;
reg.B.Field3 =1;
reg.B.Field4 =1100;
,现在如果我更改1111 0 1 0 1
会影响Fields 1,3,4
中的值吗?
答案 0 :(得分:1)
好的,请先检查下面的代码
#include <stdio.h>
typedef struct _BITS{
unsigned char f1:1;
unsigned char f2:1;
unsigned char f3:1;
unsigned char f4:1;
unsigned char f5:4;
}BITS;
typedef union {
unsigned char a;
char b;
BITS c;
}u1;
int main(void) {
u1 reg;
reg.a = 255;
reg.c.f1 = 0;
//reg.c.f2 = 1;
printf("%d", reg.c.f1);
printf("%d", reg.c.f2);
return 0;
}
为了模仿ReadRegister()
,我写了reg.a = 255
。所以现在当我写reg.c.f1 = 0
并且它正在改变所有位时,reg.c.f2
也会打印0。但它不会发生。 Bitfield仅针对该特定位,而不是整个字节。因此不,它只会清除那个位
现在,如果我写reg.a = 0
和reg.c.f1 = 255
,如果它设置了所有位,那么reg.c.f2
将产生1但不会。因此不能你不能设置位字段的所有位
修改强> 但是你可以用其他方式设置多个位。参见@sdao的答案
希望能回答你的问题
答案 1 :(得分:0)
1:您可以单独更改字段而不影响其他字段 2:您可以同时更改多个字段。
仅供参考:在您的情况下,可以将值设置为每个字段[0: sizeof(unsigned char)]
,但每个字段可以接收的实际值取决于它的位数,因此请小心
假设您有 N 位字段,则将 M 分配给该字段,然后将设置的实际值为:(M & (N^2 - 1))
其中{{1}是面具。
例如:
(N^2 - 1)