基于CAN通信的基础学习---C语言位操作

基于CAN通信的基础学习—C语言位操作

所谓的CAN通信,基本上所有的汽车的整车和别的电子模块的通信方式。

当然本文不是讲解CAN通信的,稍微简单的提一下:所有的通信方式都会有

接收方和发送方,你需要进行通信的话,需要几个基本的原则:

两方都需要同一个波特率,需要相同的(协议)

协议:好像很牛逼的名词,内存能够操作的最小单元是字节,一般协议就是规定

双方能够接受的语言(接收方和发送方),其实就是规定你的报文的每一位对应

的意义,比如你在第一个字节传一个输出电压。。等等

常用的位操作符

因为是做嵌入式开发,后面的数都统一是无符号数

1、位与 &    与 逻辑与&&

位与故名思意就是指一个无符号的数每一位(bit只有两种情况要么1要么0)进行与运算

与运算的特点:

只有两个位都为1的时候,相与才会是真1

只要有一个数不是1的话,那么就是假0

逻辑与&&

就是指一个数(可能它占8位也可能占32位)

一个数只有两种情况:要么是0,要么就不是0

当两个数进行逻辑与的时候,那么只要其中一个数不是0的话,或者两个数都不是0,那么

逻辑与得出的结果就是1

2、位或 |     与   逻辑或 ||

跟位与与逻辑与的区别是一样的,一个是进行每位之间的运算,一个是整体进行或运算

位或的特点:只有两个数等于0的时候才会是0

3、位取反~   与逻辑取反!

位取反的意思就是当位等于1的时候就是0,当位等于0的时候就是1

逻辑取反!

就比较的有意思了,一个非0的数,取反后就是0

0取反后就是1

4、位异或^

真值表:1^1=0     0^0=0    1^0=1   0^1=1

位异或的特点就是两个位如果相等的话就是0,如果不相等的话就是1

连续异或两个相同的数,得到的值是保持不变的,可以用作密码使用。

5、左移<<     右移>>   箭头朝哪个方向,那么就是向哪里移动。

C语言的移位要取决于数据类型,对于无符号的数来说,怎么移动都可以通过补充0来解决。

对于无符号数,左移时右侧补0(相当于逻辑移位)

对于无符号数,右移时左侧补0(相当于逻辑移位)

对于有符号数,左移时右侧补0(叫算术移位相当于逻辑移位)

(有符号的数需要知道最前面的那一位是符号位,但是左移相当于增大了一倍,所以也是相当于逻辑移位)

对于有符号数,右移时左侧补符号位(叫算术移位,如果是正数补0,负数就是补1)

6、如果操作寄存器

当我想要改变一个寄存器中的某些特定位的时候,我不会直接去给他写。

我会先读出寄存器整体的原来的值,然后在这个基础上修改我想要的特定位,再

将修改值的整体写入寄存器。

在32位处理器的系统中,寄存器的读写一般都是32位一起进行的

这样达成的效果是:在不影响其他位原来值的情况下,我关心的

位的值已经被修改了。

7实战演练

来自朱有鹏的C语言高级专题

特定位清零用&

回顾上节的位与的操作特点:

如果希望将一个寄存器的某些特定位变成0而不影响其他位

可以构造一个合适的1和0组成的数和这个寄存器原来的值进行位与操作,就可以将特定位清零。

举例:假设原来32位寄存器中的值0xAAAAAAAA,我们希望将bit8到

Bit15清零而其他位不变,可以将这个数与

0xffff00ff进行位与即可。

特定位置1  用位或  |

操作手法跟我们位与是一样的,要置1的特定位为1,其他位为0,将这个数原来的数位或即可。

把一个寄存器值的bit4~bit7置1,其他位不变。

4.1、给定一个整型数a,设置a的bit3,保证其他位不变

开始之前把之前的内存

a = a | (1 << 3)

4.2、给定一个整型数a,设置a的bit3~bit7,保持其他位不变

a = a | (0x1f<<3)

4.3、给定一个整型a, 清除bit15,保证其他位不变

要先构建一个相反数。

a = a & (~(1 << 15))

4.4、给定一个整型a, 清除bit15~bit23,和清除bit23到bit29位,保证其他位不变,要清除bit15到23位

a = a & (~(((0x1ff << 15)) | (0x7f << 23)));

—给定一个整形数a,取出a的bit3~bit8。

思路:

第一步:先将这个数bit3~bit8不变,其余位全部清零。

第二步,再将其右移3位得到结果。

第三步,想明白了上面的2步算法,再将其转为C语言实现即可。

a &= (0x3f<<3);

a >>= 3;

----用C语言给一个寄存器的bit7~bit17赋值937(其余位不受影响)。

思路:第一步,先将bit7~bit17全部清零,当然不能影响其他位。

你并不知道bit7~bit`17赋值937

第二步,再将937写入bit7~bit17即可,当然不能影响其他位。

你要赋值的时候哦需要先对原来的数清0

a &= ~(0x7ff<<7);

a |= (937<<7);

技术升级:用宏定义来完成位运算。

#define SET_NTH_BIT(x, n)  (x | ((1U)<<(n-1)))      //将32位数x的第n位复位,1U是 指1是无符号数(是有好处的,无符 号数左移右移都补0,有符号数的负数左移时补1)

#define CLEAR_NTH_BIT(x, n) (x & ~((1U)<<(n-1)))     //将32位数的第n位清零

作者:conding123
来源:CSDN
原文:https://blog.csdn.net/dhauwd/article/details/77422369
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值