riv*_*run 5 c macros c-preprocessor
我正在使用 C 语言开发微控制器。其中一部分涉及更改寄存器中的位值。我想出了一些宏来使事情变得更容易:
#define BIT_SET(addr, shift) (addr | (1 << shift))
#define BIT_RESET(addr, shift) (addr & ~(1 << shift))
#define BIT_GET(addr, shift) (addr & (1 << shift))
...
reg1 = BIT_SET(reg1, 3); //set bit 3
...
Run Code Online (Sandbox Code Playgroud)
但是,现在我想制作一个可以一次更改几位的宏。例如,可能想要将 的前 3 位更改10101010为110,从而得到数字11001010。
我可以在 C 中做到这一点吗?还是我以错误的方式接近这个?
You could introduce a fullwidth mask which defines the bits you want to set. E.g. for setting the first 3 bits use 0xe0, which is in binary 11100000.
Along with that mask, provide the value to write also in full width.
E.g. 0xc0 for the desired binary 110 in the first three bits.
Then a little bit-operatino magic is needed to only write the desired bit positions.
#define MULTIBIT_SET(addr, mask, value) (((addr)&((0xff)^(mask)))|((value)&(mask)))
Run Code Online (Sandbox Code Playgroud)
Here ((0xff)^(mask)) inverts the mask, so that anding with this deletes the existing bits from the value.
((value)&(mask)) is the value but with only set bits in the desired positions, i.e. this prevents undesired setting of bits elsewhere.
In total, oring the two parts, gives you the desired result.
这里有一个设计选择,我想提一下:
称之为偏执狂。如果有人告诉我“我只想将前三位设置为在其他地方有位的值”,那么我更愿意以这种方式安全,即删除“其他位”。
是的,我假设无意中设置位比不设置位风险更大,这是一个品味问题。