今天给大家继续分享C语言里面的位操作;这个礼拜熟悉了一下公司代码,第一次看内核代码的感受就是(看的是 rtos——threadx 和 Linux),C 语言基础要好,不然看源代码很是难受,而且一般企业里面的项目都是非常庞大的,所有的一切都要靠自己去理解,所以的话平时一些c语言基础要掌握好,比如说:指针,二级指针,函数指针,指针函数,结构体数组指针,结构体指针数组,数组指针,指针数组,结构体等,甚至一些 GNU 里面的c 语言用法,可能在平时的单片机代码里面不是很常见,比如说: attribute 的多种用法,week 弱定义,volatile 的使用,内联函数的使用,结构体位域的使用等等,当然也会有C++代码;现在越来越觉得C++和C这种语言是真的好,很强大分享,很香。想必刚才说的里面有些读者可能没用甚至也没有听过(当然您是老手的话,那可是小菜一碟啊!),没关系,作者也是一边学习一边总结的,后面也会总结分享出来的,希望对各位有用。
一、得明白位操作的用武之地:
其实大家写过单片机的程序都或多或少的接触到这个位擦做,就像当初作者学习 stm32 的时候,点亮一个 led 灯,用寄存器的方法去实现,这个至今都记忆犹新,哈哈;所以说,做底层开发的话,一定要会位操作,也就是对一些外设寄存器的位操作,这是嵌入式工程师必备的一个小技能。
二、位操作的几种特殊实现方式:
1、特定位清零用"&":
我们在对外设寄存操作的话,就经常要这样干,以至于来实现自己想要的功能来。比如说如果希望将一个寄存器的某些特定位变成 0 而不影响其他位,可以构造一个合适的 1 和 0 组成的数和这个寄存器原来的值进行位与操作,就可以将特定位清零。下面我们来看一个简单的例子(假设原来 32 位寄存器中的值为:0xaaaaaaaa,我们希望将 bit8 ~bit15 清零而其他位不变,可以将这个数与0xffff00ff进行位与即可。):
#include <stdio.h>
int main(void)
{
unsigned int a=0xaaaaaaaa;
unsigned int b=0xffff00ff;
unsigned int c =a&b;
printf("the c is 0x%x\n",c);
return 0;
}
输出结果:
the c is 0xaaaa00aa
2、特定位置1用 "|":
首先我们要明白一点:任何数,(其实就是1或者0)与1位或变成1,与0位或无变化。再明白了这一点后,我们来看一个例子(把一个寄存器值的bit4~bit7置1,其他位不变):
#include <stdio.h>
int main(void)
{
unsigned int a = 0x123d0cd7;
unsigned int b = 0xf0;
unsigned int c;
c = a | b;
printf("a & b = 0x%x.\n", c);
return 0;
}
输出结果:
a & b = 0x123d0cf7.
注意:bit位是用bit0开始的。
3、特定位取反用 "^":
同样,首先要明白的"^"的基本用法:任何数,其实就是1或者0)与1位异或会取反,与0位异或无变化。所以,我们要构造这样一个数:要取反的特定位为1,其他位为0,然后将这个数与原来的数进行位异或即可。下面我们来看一个例子(把一个寄存器值的bit4~bit7取反,其他位不变):
#include <stdio.h>
int main(void)
{
unsigned int a = 0x123d0c37;
unsigned int b = 0xf0;
unsigned int c;
c = a ^ b;
printf("a & b = 0x%x.\n", c);
return 0;
}
输出结果:
a & b = 0x123d0cc7.
4、使用移位(或者有位操作符结合)获取特定位为1或者0的二进制数:
这种用法,用的比较多,比如说用"<<"(左移操作)和">>"(右移操作)移位操作来获得自己想要的目标结果,而且还会和我们上面讲的位操作符来结合使用;这里我们来看两个例子:
#include <stdio.h>
int main(void)
{
unsigned int a ;
a = ((0x1f<<3) | (0x7<<23));
printf("a = 0x%x.\n", a);
return 0;
}
输出结果:
a = 0x38000f8.
说明:
这里0x1f左移3位的话就成了0xf8了,然后0x7左移23位的话,就成了 0x3800000,然后两者再进行或操作,最后结果就是0x38000f8了。
#include <stdio.h>
int main(void)
{
unsigned int a;
a = ~(0x7f<<4);
printf("a = 0x%x.\n", a);
return 0;
}
输出结果:
a = 0xfffff80f.
5、小结:
三、总结:
好了,今天的分享就到这里了,更多位操作实战演示在下篇文章中继续分享。希望今天的分享对你有帮助!感谢您的收看!