天天看点

C编程中位操作的常见技巧(含个人项目经验)

最近思来想去,觉得需要技术沉淀,于是我注册了个微信公众号(airX嵌入式),这也是为我后续创业公司做准备,一来能分享记录我的开发项目,以及开源一切设计;二来能结识更多的同道中人!有机会可以合作创业!

微信扫码关注我!(airX嵌入式)

C编程中位操作的常见技巧(含个人项目经验)

在C项目中,我们常常会遇到设置某个参数中的n位数值或者读取某个参数的n位数值,如果每次都口算出整个参数的值再使用与或算法那真的费时间,弄不好算错了那就更麻烦了!

举个例子:假设寄存器A为32Bit长度寄存器,请将27位的值置位0?

如果你傻傻的有下面这个做法,那建议你把这篇文章看完,对你肯定有帮助。

做法:根据与或运算法则,算出当27位为0,其他位为1的32bit的值为

0xF7FFFFFF;

然后A &=0xF7FFFFFF;

为了杜绝上面的麻烦和错误的风险!

下面我列举几个常见的操作,也是本人写代码的操作:

声明:以下说到的寄存器当然是可以读取写入的寄存器

写操作:

1、把寄存器/变量的第n位清零,不改变其他位的数值

  void a;

  a= 0x12345678;

 a &=~(1<<12);  //第12bit置0,其他不变;

同理:a &= ~(1<<27); //第27bit置0,其他不变;

公式:a &=~(1<<n);

2、把寄存器/变量的第n位起的连续m位清零,不改变其他位的数值

 void a;

a = 0x12345678;

a &= ~(3<<1); //第1位起的连续2位清零

a &= ~(7<<2); //第2位起的连续3位清零

公式 a &= ~((2^m-1)<<n);

2^m-1表示的是m位都为1的二进制的十进制数值,比如3表示二进制0b00000011,表示连续2位;7表示二级制0b00000111,表示连续3位;

3、把寄存器/变量的第n位置1,不改变其他位的数值

 void a;

a = 0x12345678;

a |= (3<<1); //第1位起的连续2位置1

a |= (7<<2); //第2位起的连续3位置1

公式:a |=(1<<n);

4、把寄存器/变量的第n位起的连续m位置1,不改变其他位的数值

 void a;

a = 0x12345678;

a |= (3<<1); //第1位起的连续2位置1

a |= (7<<2); //第2位起的连续3位置1

公式 a |= ((2^m-1)<<n);

2^m-1表示的是m位都为1的二进制的十进制数值,比如3表示二进制0b00000011,表示连续2位;7表示二级制0b00000111,表示连续3位;

5、对寄存器/变量的第n位取反

 void a;

a = 0x12345678;

a ^= (1<<1); //第1位取反

a ^= (1<<2); //第2位取反

公式:a ^= (1<<n);

读操作:

1、读寄存器/变量的第n位

 void a,result;

a = 0x12345678;

result=a& (1<<2); //读第2位

result=a& (1<<3); //读低3位

公式:result=a& (1<<n); 

2、读寄存器/变量的第n位起的连续m位

 void a,result;

a = 0x12345678;

result=a& (3<<2); //读第2位开始的连续2位数据

result=a& (3<<27); //读第27位开始的连续2位数据

公式result=a& ((2^m-1)<<n); 

2^m-1表示的是m位都为1的二进制的十进制数值,比如3表示二进制0b00000011,表示连续2位;7表示二级制0b00000111,表示连续3位;

像这种操作,判断时可以完全脱离位置的计算,只需看变量名称就可操作!

下面这些是别人厂家的库函数:也是如此定义

C编程中位操作的常见技巧(含个人项目经验)
C编程中位操作的常见技巧(含个人项目经验)

清除的操作:

C编程中位操作的常见技巧(含个人项目经验)

清除置位都有的函数,只需传入上面宏定义的参数即可操作;

C编程中位操作的常见技巧(含个人项目经验)

下面是我的一个断路器项目,其中因为要记录各种故障原因,因此需要很多的标志位!

1、我的第一步操作就是使用位移操作宏定义故障原因,如下1,以及一个缓存故障原因的缓存变量,如图2;

C编程中位操作的常见技巧(含个人项目经验)

图1

C编程中位操作的常见技巧(含个人项目经验)

图2

2、构建获取相应故障状态的函数,如下操作:

C编程中位操作的常见技巧(含个人项目经验)
C编程中位操作的常见技巧(含个人项目经验)

3、构建清除相应故障状态的函数,如下操作:

C编程中位操作的常见技巧(含个人项目经验)

4、构建设置相应故障状态的函数,如下操作:

C编程中位操作的常见技巧(含个人项目经验)

最后只需调用,传入相应的故障宏定义即可!这样做的话,直接读函数名就可以知道该函数的作用!避免当枚举太多,导致混乱!

微信扫码关注我!(airX嵌入式)

C编程中位操作的常见技巧(含个人项目经验)

继续阅读