位运算
位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果。
位运算符
&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。
1.按位取反运算符是单目运算符,其余均为双目运算符。
2.位运算符的优先级从高到低,依次为~、&、^、|,
3.其中~的结合方向自右至左,且优先级高于算术运算符,其余运算符的结合方向都是自左至右,且优先级低于关系运算符。
(一)按位与(&)运算规则:
只有两个数的二进制同时为1,结果才为1,否则为0。
0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
按位或(|)运算规则:
参加运算的两个数只要两个数中的一个为1,结果就为1。
0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。
在嵌入式开发中,经常会操作寄存器,对寄存器进行配置。
&= 一般用在复位,即清零,将=号后面0的位清零,1的位保持不变。|=* 一般用在置位,即置1,1的位置1,0的位保持不变。两者结合一起用,先复位,后置位。***
按位异或运算符(^):
按位异或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相应位的值相同的,结果为 0,不相同的结果为 1。
按位异或运算的典型用法是求一个位串信息的某几位信息的反。
按位取反运算符(~):
按位取反运算是单目运算,用来求一个位串信息按位的反,即哪些为0的位,结果是1,而哪些为1的位,结果是0。
取反运算常用来生成与系统实现无关的常数。
移位运算
移位运算用来将整型或字符型数据作为二进位信息串作整体移动。有两个运算符: << (左移) 和 >> (右移)
移位运算是双目运算,有两个运算分量,左分量为移位数据对象,右分量的值为移位位数。移位运算将左运算分量视作由二进位组成的位串信息,对其作向左或向右移位,得到新的位串信息。移位运算符的优先级低于算术运算符,高于关系运算符,它们的结合方向是自左至右。
byte的清零,置1,提取(编程驱动常见的操作)
第几位需要置1就将0x01左移几位。
例如GPIOx_CRL |= (0x01 << 2);`就是将GPIOx_CRL的第二位(bit1)置1
给定一个整形数a,清除a的bit15~bit23,保持其他位不变。
a &= ~(0x1FF<<15);
给定一个整形数a,设置a的bit3~bit7,保持其他位不变。
a |= 0x1F<<3; 0x1F=0001 1111 也就是将寄存器的第3到7位全部置1
给定一个整形数a,取出a的bit3~bit8。
a = (a>>3) & 0x3F
例子:
1.把变量的某位清零
先定义一个随机变量a
unsigned char a = 0x9f;
对bit2位进行清零操作
a &= ~(1 << 2); //把数字1左移两位进行与运算并且取反
0x9f = 1001 1111
对bit2位清零就是将1001 1111变为 1001 1011
第一步:1左移两位,得到0000 0100
第二部:取反得到1111 1011
第三步: a&= 1111 1011 可以写为 a=(1001 1111) & (1111 1011)得到 1001 1011
2.把变量的连续几位清零
a &= ~(3<<2*1);
3.对变量的某一位进行复制操作
a |= (1<<3);
4.对变量的某几位进行赋值操作
//假设a = 1000 0011 b,将第二组bit4bit5设置成二进制数 01 b
a |= (1<<2*2);
寄存器在经过清零操作之后,就可以很方便的在某几位写入所需要的数值且保持其他位不变,这时候写入的数值一般就是需要设置的寄存器位参数了。
5.对某位进行取反操作
//a = 1001 0011 b 对bit6位进行取反
a ^= (1<<6);
//a = 1101 0011 b