C语言按位运算符
在嵌入式编程中,常常需要对一些寄存器进行配置,有的情况下需要改变一个字节中的某一位或者几位,但是又不想改变其它位原有的值,这时就可以使用按位运算符进行操作。下面进行举例说明,假如有一个8位的TEST寄存器:
当我们要设置第0位bit0的值为1时,可能会这样进行设置:
TEST = 0x01;
但是,这样设置是不够准确的,因为这时候已经同时操作到了高7位:bit1~bit7,如果这高7位没有用到的话,这么设置没有什么影响;但是,如果这7位正在被使用,结果就不是我们想要的了。
在这种情况下,我们就可以借用按位操作运算符进行配置。
对于二进制位操作来说,不管该位原来的值是0还是1,它跟0进行&运算,得到的结果都是0,而跟1进行&运算,将保持原来的值不变;不管该位原来的值是0还是1,它跟1进行|运算,得到的结果都是1,而跟0进行|运算,将保持原来的值不变。
所以,此时可以设置为:
TEST = TEST | 0x01;
其意义为:TEST寄存器的高7位均不变,最低位变成1了。在实际编程中,常改写为:
TEST |= 0x01;
这种写法可以一定程度上简化代码,是 C 语言常用的一种编程风格。设置寄存器的某一位还有另一种操作方法,以上的等价方法如:
TEST |= (0x01 << 0);
第几位要置1就左移几位。
移位:高位丢弃,低位补0,得到新值
同样的,要给TEST的低4位清0,高4位保持不变,可以进行如下配置:
TEST &= 0xF0;
把变量的某位清零
//定义一个变量a = 1001 1111 b (二进制数)
unsigned char a = 0x9f;
//对bit2 清零
a&=~(1<<2);
//括号中的1左移两位,(1<<2)得二进制数:0000 0100 b
//按位取反,~(1<<2)得1111 1011 b
//假如a 中原来的值为二进制数: a = 1001 1111 b
//所得的数与a 作”位与&”运算,a = (1001 1111 b)&(1111 1011 b)
//经过运算后,a 的值 a=1001 1011 b
// a 的bit2 位被被零,而其它位不变。
把变量的某几个连续位清零 ```c //若把a 中的二进制位分成2 个一组 //即bit0、bit1 为第0 组,bit2、bit3 为第1 组 // bit4、bit5 为第2 组,bit6、bit7 为第3 组 //要对第1 组的bit2、bit3 清零
a &= ~(3<<2*1);
//括号中的3左移两位,(3<<21)得二进制数:0000 1100 b //按位取反,~(3<<21)得1111 0011 b //假如a 中原来的值为二进制数: a = 1001 1111 b //所得的数与a 作”位与&”运算,a = (1001 1111 b)&(1111 0011 b) //经过运算后,a 的值 a=1001 0011 b // a 的第1 组的bit2、bit3 被清零,而其它位不变。
//上述(~(3<<2*1))中的(1)即为组编号;如清零第3 组bit6、bit7 此处应为3 //括号中的(2)为每组的位数,每组有2 个二进制位;若分成4 个一组,此处即为4 //括号中的(3)是组内所有位都为1 时的值;若分成4 个一组,此处即为二进制数“1111 b”
//例如对第2 组bit4、bit5 清零 a &= ~(3<<2*2);
3. 对变量的某几位进行赋值
```c
//a = 1000 0011 b
//此时对清零后的第2 组bit4、bit5 设置成二进制数“01 b ”
a |= (1<<2*2);
//a = 1001 0011 b,成功设置了第2 组的值,其它组不变
- 对变量某位取反 ```c //a = 1001 0011 b //把bit6 取反,其它位不变 a^=(1<<6);
//a = 1101 0011 b ```