如何写入单个位?我有一个变量,其值为1或0,我想将其值写入8位reg
变量中的单个位。
我知道可以使用以下代码设置单个位:
reg |= mask; // mask is (1 << pin)
这会稍微清晰一些:
reg &= ~mask; // mask is (1 << pin)
有没有一行代码可以做到这一点,而不需要确定输入值是高还是低?
假设 value
的值为 0
或 1
:
REG = (REG & ~(1 << pin)) | (value << pin);
我使用REG
代替register
,因为如@KerrekSB在评论中指出的那样,register
是一个C语言关键字。
这里的想法是我们计算一个具有指定位清除的REG
值,然后根据value
的不同设置该位。
reg = a | b;
本身并不意味着分支,这显然是不需要的。 - wildplasserpin
是一个函数参数,那么这个假设就不成立了,因为参数并不是C常量。 - ouah因为你将这个标签打上了 embedded,所以我认为最好的答案是:
if (set)
reg |= mask; // mask is (1 << pin)
else
reg &= ~mask; // mask is (1 << pin)
if (set) reg_set = mask; else reg_clr = mask;
。由于寄存器被定义为“volatile”对象,编译器没有权利自行执行此优化(即用reg_set / reg_clr
替换reg
)。 - ouahC语言中一个被忽视的特性是位域(bit packing),它非常适合嵌入式开发。你可以定义一个struct
来单独访问每个位。
typedef struct
{
unsigned char bit0 : 1;
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char bit3 : 1;
unsigned char bit4 : 1;
unsigned char bit5 : 1;
unsigned char bit6 : 1;
unsigned char bit7 : 1;
} T_BitArray;
< p > :1
告诉编译器您只希望每个变量的长度为1位。然后只需访问变量reg
所在的地址,将其转换为位数组,然后逐个访问位。 < / p >
((T_BitArray *)®)->bit1 = value;
®
是您变量的地址。 ((T_BitArray *)®)
是相同的地址,但现在编译器将其视为一个T_BitArray
地址,((T_BitArray *)®)->bit1
提供访问第二位的方法。当然,最好使用比bit1
更具描述性的名称。
//Through Macro we can do set resset Bit
#define set(a,n) a|=(1<<n);
#define reset(a,n) a&=(0<<n);
//toggle bit value given by the user
#define toggle(a,n) a^=(1<<n);
int a,n;
int main()
{
printf("Set Reset particular Bit given by User ");
scanf("%d %d",&a,&n);
int b =set(a,n) //same way we can call all the macro
printf("%d",b);
return 0;
}
我认为你所问的是是否可以在不先读取所在字节的情况下执行单个位的写入指令。如果是这样,那么不,你不能这样做。这与C语言无关,只是微处理器没有寻址单个位的指令。即使在原始机器代码中,如果要设置一个位,您必须先读取它所在的字节,更改该位,然后将其写回。没有其他方法可以做到。
这是如何设置、清除和切换单个位的副本,我也会重新发布我的答案,因为还没有人提到SET和CLEAR寄存器:
由于这个标签是“嵌入式”,我假设您正在使用微控制器。上述所有建议都是有效的并且可行的(读取-修改-写入、联合、结构等)。
register
是 C 语言中的一个关键字,你不能将其用作变量名。 - Kerrek SB