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

本文介绍了在C语言中如何高效地对32位寄存器进行位操作,包括设置、清除、读取特定位以及连续位的操作,并通过实例展示了如何避免计算错误。此外,还分享了在实际项目中如何组织和使用宏定义来简化位字段管理,以提高代码可读性和维护性。
摘要由CSDN通过智能技术生成

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

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

 

在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位;

 

 

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

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

图片

 

图片

清除的操作:

图片

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

图片

 

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

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

图片

图1

图片 

图2

 

 

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

 

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

图片

 

 

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

图片

 

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

 

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值