位与、位或、位异或的特点总结
&:(任何数,其实就是1或者0)与1位与无变化,与0位与变成0。
|:(任何数,其实就是1或者0)与1位或变成1,与0位或无变化。
^:(任何数,其实就是1或者0)与1位异或会取反,与0位异或无变化。
左移位<< 与 右移位>>
C语言的移位要取决与数据类型。
对于无符号数,左移时右侧补0(相当于逻辑移位)
对于无符号数,右移时左侧补0(相当于逻辑移位)
对于有符号数,左移时右侧补0(叫算术移位,相当于逻辑移位)
对于 有符号数,右移左侧补符号位(如果正数就补0,负数就补1,叫算术移位)
嵌入式中研究的移位,以及使用的移位都是无符号数。
示例
1、给定一个整型数a,设置a的bit3,保证其他位不变。
a|=(1<<3);
2、给定一个整形数a,设置a的bit3~bit7,保持其他位不变。
a|=(0x1f<<3);
3、给定一个整型数a,清除a的bit15,保证其他位不变。
a&=~(1<<15);
4、给定一个整形数a,清除a的bit15~bit23,保持其他位不变。
a&=~(0x1ff<<15);
5、给定一个整形数a,取出a的bit3~bit8。
思路:
第一步:先将这个数bit3~bit8不变,其余全部清零。
第二步:再将其右3位得到结果。
a&=(0x3f<<3);
a >>= 3;
6、用C语言给一个寄存器的bit7~bit17赋值937(其余位不受影响)。
关键点:第一,不能影响其他位;第二,你并不知道原来bit7~bit17中装的值。
思路:
第一步,先将bit7~bit17全部清零,当然不能影响其他位。
第二步,再将937写入bit7~bit17即可,当然不能影响其他位。
a&=~(0x7ff<<7);
a|=(937<<7);
7、用C语言将一个寄存器的bit7~bit17中的值加17(其余位不受影响)。
关键点:不知道原来的值是多少。
思路:
第一步,先读出原来bit7~bit17的值。
第二步,给这个值加17。
第三步,将bit7~bit17清零。
第四步,将第二步算出来的值写入bit7~bit17。
uint tmp = 0
tmp = a & (0x3ff<<7);
tmp >>= 7;
tmp += 17;
a &= ~(0x3ff<<7);
a |= (tmp << 7);
8、直接用宏来置位、复位(最右边位第1位)。
#define SET_NTH_BIT(x, n) (x | ((1U)<<(n-1)))
#define CLR_NTH_BIT(x, n) (x & ~((1U)<<(n-1)))
9、截取变量的部分连续位。例如:变量0x88,也就是10001000b,若截取第2~4位,则值为:100b = 4
#define GETBITS(x, n, m) ((x & ~(~(0U)<<(m-n+1))<<(n-1)) >> (n-1)