文章目录
一、理论知识二、如何对某一位置0或者置1?方法一:方法二:方法三:
三、位操作的实际应用(最经典,必看)四、特定二进制数的获取
参考 博文01:https://blog.csdn.net/hongjiujing/article/details/2178593
一、理论知识
学习本节课之前要先去学习位运算操作符的理论知识,注意运算符之间的优先级。
1、 位操作运算符 :非~ 与 & 或 | (优先级顺序是 非~ 与 & 或 | ) 2、逻辑运算符 : 非! 与&& 或 || (优先级顺序是 非! 与&& 或 || )
3、^ 异或运算符———不同则为1,相同则为0 // 当且仅当两个运算值中有一个为1但不同时为1时,返回值为1 4、位操作运算符 : 优先级也是以下顺序排列的
~ 非(也叫按位取反运算符) << (左移) >> (右移) & 与 (按位与) ^ (按位 “异或”) | 或 (按位或)
二、如何对某一位置0或者置1?
方法一:
写成宏,方便移植 #define setbit(x,y) x|=(1< 方法二: C语言位运算除了可以提高运算效率外,在嵌入式系统的编程中,它的另一个最典型的应用,而且十分广泛地正在被使用着的是位间的与(&)、或(|)、非(~)操作,这跟嵌入式系统的编程特点有很大关系。我们通常要对硬件寄存器进行位设置 譬如,我们通过将AM186ER型80186处理器的中断屏蔽控制寄存器的 第低6位设置为0(开中断2),最通用的做法是: #define INT_I2_MASK 0x0040 wTemp = inword(INT_MASK); outword(INT_MASK, wTemp &~INT_I2_MASK); 而将该位设置为1的做法是: #define INT_I2_MASK 0x0040 wTemp = inword(INT_MASK); outword(INT_MASK, wTemp | INT_I2_MASK); 判断该位是否为1的做法是: #define INT_I2_MASK 0x0040 wTemp = inword(INT_MASK); if(wTemp & INT_I2_MASK) { … /* 该位为1 */ } 方法三: int a|=(1< 博客02:https://blog.csdn.net/u010665638/article/details/84726301 三、位操作的实际应用(最经典,必看) 一般在操作寄存器的时候使用,如32位的arm寄存器,每个位代表的pin脚不同,效果也不同。有时候你只想改变某个pin脚的值从而实现某项功能,其余pin脚保持不变,就得使用位操作,只对目标位进行操作。操作的方式是:读->改->写。不要直接给寄存器赋目标值是因为你只知道要把目标位设置为某值,但是其他的位你并不知道原本是多少,所以要先读取这个寄存器的整体值,然后再修改其中的目标位,然后再把修改后的值写到寄存器。 1)特定位清零用& 譬如:将0xAAAAAAAA 的bit8 ~bit15清零,其他位保持不变。 分析:[位与]任何数(0/1)与1位与时为本身,与0位与为0,所以可以用位与的方式。 unsigned int a = 0xAAAAAAAA; unsigned int b = 0xFFFF00FF; unsigned int c; c = a & b; printf("c = 0x%x ", c); //c = 0xaaaa00aa 2)特定位 置1用 | 譬如:将0xffff00ff的bit8 ~bit15置1,其他位保持不变。 分析:位或 任何数(0/1)与1位或变为1,与0位或为本身 unsigned int a = 0xffff00ff; unsigned int b = 0x000ff00; unsigned int c; c = a | b; printf("c = 0x%x ", c); // = 0xffffffff 3)特定位取反用 ^ 譬如:将0xffff00ff的bit8 ~bit15取反,其余保持不变 分析:位异或 任何数(0/1)与1位异或会取反,与0位异或为本身 unsigned int a = 0xffff00ff; unsigned int b = 0xff00; unsigned int c; c = a ^ b; printf("c = 0x%x ", c); // = 0xffffffff 四、特定二进制数的获取 由于上面示例中的unsigned int b的值太过于呆板,后续看代码的时候可能不知道为什么是这个值,所以需要以另外的方式来表达(主要是通过位移和位取反来获取这个特定的二进制数)。 (1) 譬如:unsigned int b = 0xff00; 中的0xff00 可表示为:0xFF<<8 (0xFF :8个二进制1 <<: 左移 8: 8位) (2) 需要一个bit3 ~bit7, bit23 ~bit25为1的数(隐含意思是其他位都为0) 可为:0x1F<<3 | 0x7<<23 1F (7-3+1=5个1,转换为十六进制则为1F); 7 ( 25-23+1=3个1,转换为十六进制则为7) | ( 位或,任何数与1位或都为1,与0位或为本身,所以这里用位或就相当于把这2个位移后的数叠加起来) (3) 需要一个bit3 ~ bit7为0的数 可为:~(0x1F<<3) 总结: (1)当需要的1比较少,需要的0比较多,就使用1位移的方式; (2)当需要的0比较少,需要的1比较多,就使用位移然后取反的方式;(3)当需要的数比较复杂,如bit3 ~ bit7,bit23~bit25为1,就可以先位移然后位或的方式。