一:按位与&(AND)
只有当两位都为1时,结果才为1,否则都为0
例如:我们要改变GPIOA状态,对它的CRL寄存器某些位的值用&来改变
GPIOA->CRL&=0XFFFFFF0F; //将第 4-7 位清 0
将此16进制数换算成二进制再进行&运算可知,F就是1111了,只有第四位到第七位的数全为0(2进制是从第0位开始的),于是就得到新的值了。
二:按位异或^(XOR)
只有当两位不同时,它的结果才是1,否则为0
例如假设我们要将寄存器所有位都进行取反
GPIOA->CRL^=0XFFFFFFFF; //所有位刚好相反
当原来位是1时变为0,原来位是0时变为1.
三:按位或|(OR)
为什么我要放在第三个来说明呢?
因为这里有个隐含的关系就是:|=&+^
进行OR操作时只有两位都为0结果才是0,否则都为1,这样我们通过简单的数学逻辑就可以得出这个关系了,下面让我们具体来看看按位操作的应用吧!
GPIOA->CRL|=0X00000040; //设置相应位的值,不改变其他位的值
这是在例1的按位与上进行的,第四到第七位都是0,其余位都是1,这里运算的最终结果就是其余位还是1不变,第四到第七位中只有第六位变成了1。
四:移位:左移<< 右移>>
移位操作符最大的特点就是提高代码的可读性,如果你想赋一个值,完全可以用最简单易懂的方法直接用=去赋值,但为什么要通过左移而不是直接设置一个固定的值呢?其实,这是为了提高代码的可读性以及可重用性。
例如:我们将BSSR寄存器的第pipipink位(4,5位)设置为1的话,可以直接
GPIOx->BSRR =0x00000030;//第4,5位为1
但这样的话要是想改变数值就很麻烦了。
不妨可以这样做
GPIOx->BSRR = (((uint32_t)0x01) << pipipink);//把指定位设置为1
这样的话就提高了程序的可读性,并且容易操作位。
五:取反~
表示对其操作数进行求补运算,即0变为1,1变为0。
在单片机编程中,假设我们要设置某一位为1,其余位为0的话,同样可以采取直接赋值的方法:
例如16位寄存器SR第0位为0,其余位为1:
TIMx->SR=0xFFFE;//第0位为0。
但是这样的作法同样不好看,并且可读性很差。看看用取反操作的方法:
#define TIM_FLAG_Update ((uint16_t)0x0001)//宏定义
TIMx->SR = (uint16_t)~TIM_FLAG_Update;
这里使用了宏定义,把TIM_FLAG_Update初始数值第0位设置为了1,再取反操作,可读性非常强。
|