**位操作
在STM32的寄存器操作中,常常用到(32位)位运算。
位运算要将数据转换为2进制来进行运算
基础原理是:
&用作清零:
1&x=x; 0&x=0;| 用作置一:
1|x=1; 0|x=x;^用作取反:
1^x=(~x); 0^x=x;
下面的操作只改变特定的位,其他位保持不变。
以下操作的32位数据位 data = 0x12345678
将某一位清零
清零方式是:将要清零的位,&0 = &(~1)
~:取反
将data的第4位清零: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
& 1111 1111 1111 1111 1111 1111 1110 1111
结果为:0001 0010 0011 0100 0101 0110 0110 1000
简化为:data = data & ~(1<<4) (这就是所谓的“读写改”操作)
=> data &= ~(1<<4)
总结:
将某一位清零:
&= ~(1 << x)x是对应的位
将连续的多个位清零
清零方式是:将要清零的位,&0 = &(~1)
将data的第3~5位清零: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
& 1111 1111 1111 1111 1111 1111 1100 0111
结果为:0001 0010 0011 0100 0101 0110 0100 0000
简化为:data = data & ~(111B<<3) = data & ~(0x7<<3)
=> data &= ~(0x7<<3)
总结:
将连续的多个位清零:
&= ~(0x? << x)?:对应连续的位值转换为16进制x:最低的位
某一位置一
置一方式是:将要置一的位,|1
将data的第2位置一: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
| 0000 0000 0000 0000 0000 0000 0000 0100
结果为:0001 0010 0011 0100 0101 0110 0111 1100
简化为:data = data | (1<<2)
=> data |= (1<<2)
总结:
将某一位清零:
|= (1 << x)x是对应的位
将连续的多个位置一
置一方式是:将要置一的位,| 1
将data的第0~2位置一: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
| 0000 0000 0000 0000 0000 0000 0000 0111
结果为:0001 0010 0011 0100 0101 0110 0111 1111
简化为:data = data | (111B<<0) = data | (0x7<<0)
=> data |= (0x7<<0)
总结:
将连续的多个位置一:
|= (0x? << x)?:对应连续的位值转换为16进制x:最低的位
将某一位取反
原理同上:
方法:
data ^= (0x1 << x);data是要位取反的数据,x哪一位要取反
将连续的多个位取反
原理同上:
方法:
data ^= (0x? << x);data是要位取反的数据,?是取反位对应的16进制数,x哪一位要取反
将某些位设置成想要的数
实现方式:先用&0,将多个位都清零; 后用 | 1,将对应位置一
将data的第7~12位置为 101101: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
1、清零所有位 & 1111 1111 1111 1111 1110 0000 0111 1111
data &= ~(111111B<<7) &= ~(0x3F<<7)
结果: 0001 0010 0011 0100 0100 0000 0111 1000
2、置一对应位 | 0000 0000 0000 0000 0001 0110 1000 0000
data |= (101101B<<7) |= (0x2C<<7)
结果: 0001 0010 0011 0100 0101 0110 1111 1000
总结:
将某些位设置成自己想要的数,先将 所需要设置的位 全部清零,后需置位的位置1。
即:先
&=~();后|=();

浙公网安备 33010602011771号