一、寄存器操作
SOC片内外设由若干个寄存器控制,IO 操作的寄存器与内存统一编址,如果我们要操作片内外设,那么就是操作片内外设的控制寄存器。因此,控制硬件就是读写寄存器(寄存器亦可理解为特定地址的内存)。
SOC中一个寄存器的数据宽度一般是32位,每个位可以配置为0或者1,单个bit 或相邻几个bit 一起控制片上外设某个属性的状态。单个 bit 最多控制两种状态,三个 bit 最多控制8种状态。因此寄存器的特定bit配置为0或1,即可以实现对硬件的控制。
二、寄存器特定位清零(&)
假设我们希望将一个寄存器的某些特定位变成0,并且不会影响其他位的改变,我们可以构造一个合适的1和0组成的数,和原本的这个寄存器进行与运算,就可以将特定的位进行清零操作。
案例实战
例子:现在有个寄存器R = 0XAAAAAAAA ,希望将8~23位进行清零操作并且其他位保持不变
我们可以使用按位与来实现
R &= 0xFF0000FF;
运行结果为:
经过以上读、改、写操作之后,R的值为0xAA0000AA,达到了特定位清零的目的
三、寄存器特定位置1(|)
现在我们已经知道可以使用按位与(&)可以对特定寄存器进行清零操作,那么我们是否可以根据按位或的规则来对寄存的特定为进行置1操作呢?答案是可以
案例实战
例子:现在有个寄存器R = 0XAAAA00AA ,希望将8~23位进行置1操作并且其他位保持不变
具体实现程序:
int R = 0XAAAA00AA;
R |= 0X00FFFF00;
printf("R = 0X%02X\n", R);
实现结果:
经过以上读、改、写操作之后,R的值为0XAAFFFFAA,达到了特定位置1的目的
四、寄存器特定位取反(~)
我们前面了解了如何对特定为进行清零或者置1操作,那么我们如何实现寄存器特定为进行取反操作呢?什么是特定位取反呢?就是使特定位上的0变成1、1变成0.经过一轮分析发现使用位异或可以实现(^)
案例实战
例子:现在有个寄存器R = 0XAAAA55AA ,希望将8~23位进行取反操作并且其他位保持不变
具体实现程序:
int R = 0XAAAA55AA;
R ^= 0X00FFFF00; //进行位异或运算
printf("R = 0X%02X\n", R);
实现结果:
经过以上读、改、写操作之后,R的值为0XAA55AAAA,达到了特定位置取反目的
五、构建特定的二进制数
由前面可知,对寄存器特定位进行置1、清零或者取反,关键点在于要事先构建一个特别的数,这个数和原来的值进行位与、位或、位异或操作,即可达到我们对寄存器操作的要求。自己去算这个数,显然既费时又费脑,虽然依托工具也可以算出来,但缺点就是不直观。如0X0003803A这个数谁能一下报出转换为二进制后为多少?这个也太难了。那么应该怎么办呢?既然如此,我们完全可以使用位运算(位与、位或、取反等等)快速地构建我们需要的操作数。
5.1 移位获取特定位为1的二进制
简单的说就是通过移位的方式来获取一个特定位为1的二进制数。
案例实战
假设我们现在需要将寄存器的bit3~bit7置1,那么我们应该如何来做
首先动一动我们的小脑筋,想了一下
0b11111000 = 0xf8,然而这个数并不能一下想出来吧,那么我们有没有简单点的方法
首先咱们分析下:
bit3~bit7:以bit0为基础构造结果为0X1f
然后开始移位即可 R = (0x1f<<3)
int R = 0;
R = (0x1f << 3);
printf("R = 0X%02X\n", R);
运行结果为:
这个例子可能还不太明显的感受到
接下来咱们看另一个例子:此时我们需要将bit3~bit7置1,同事将bit23~25置1
这个时候如果采用转换二进制的方法估计会比较头大,咱们借助计算机算下,这个二进制数是多少
通过计算器计算得到R = 0X0308000f8
那么咱们有没有简便一点的方法呢?答案是当然有
第一步咱们来构造二进制
bit3~bit7:以bit0为基础构造结果为0x1f
bit23~bit25:以bit0为基础构造结果为0x07
开始进行移位操作:R = (0x1f<<3)| (0x07<<23)
代码如下:
int R = 0;
R = (0x1f << 3) | (0x07 << 23);
printf("R = 0X%02X\n", R);
结果如下:
这样计算起来就是相当的方便
5.2 结合位取反获取特定位为0
直接举例说明,原理与之气那类似
我们想要获取bit4~bit10为0,其他数全部为1。
首先咱们来分析下这个需求
bit4~bit10为0,说明bit31~bit11及bit0~bit3为1
那么构造bit0~bit3为:0x0f
构造bit11~bit31为:0x1fffff
直接进行移位梳理即可
R = (0x0f << 0)| (0x1fffff << 11)即可结果如下
通过计算器来看下0Xfffff80f这个数的4~10位是否为0;
通过计算器发现,确实可以实现特定位清零的作用
构造反码
bit4~bit10为0的数,其反码为bit4~bit10为1,其余bit为0,
其实现为:R = ~(0x7F<<4)
实现如下
六、总结
以上就是位运算在寄存器中的使用,有什么不足的地方还请大家评论补充!