如何使用单行代码设置和清除不同的位(C)

时间:2015-05-22 21:55:30

标签: c bit-manipulation bitwise-operators firmware

data |= (1 << 3)设置位(3)而不中断其他位。 data &= ~(1 << 4)在不中断其他位的情况下重置位(4)。如何在一条指令中完成这两项任务?

(因为这只是为了可读性,我计划#define#define gpioHigh(x) <insert code>之类的可爱方式进行此操作。另一种方法是弄清楚如何正确地将gpio指针传递给我的函数为此目的明确写,但是那个)

谢谢!

麦克

2 个答案:

答案 0 :(得分:5)

单指令不可能。这是因为您需要对不同的位执行3种操作:

  • 设置它们(第3位)
  • 清除它们(第4位)
  • 不管它们(所有其他位)

如何使用由二进制数字组成的位掩码从三种可能中选择一种?

当然,你可以用一行代替它,例如:

data = (data | (1 << 3)) & ~(1 << 4)

答案 1 :(得分:2)

你不能。

也就是说,如果您想明确确保bx设置并by清除 - 如果您只想翻转它们(无论先前值如何),您可以使用operator^进行异或其他人指出。

要了解为什么不能在一条指令中完成(当然,您可以轻松地将两条或更多条指令组合到一个LOC中),请考虑以下真值表:

B|A|Q
-----
0|0|x
0|1|0
1|0|1
1|1|x

&#34;不关心&#34; x与讨论无关。没有逻辑运算符具有此功能 - 它怎么可能?如果两个输入具有不同的值*,我们如何确定哪个是B哪个是A?这是你问题的核心所在。

然而,考虑将这个塞进一条指令或许并不能达到你所说的可读性目标。事实上,如果有的话,两者分别是更多可读 - 并且仍然可以被某些set3clear4()调用。

注意 - 这与切线相关 - 真值表可以通过所谓的“逻辑元素”来实现。在FPGA体系结构中,它们是由查找表和#39;构建的。 (LUT)本质上是ROM,其中输入A,B,...索引到表中以找到值Q。当然,A¬B对应的地址与¬AB不同。