**位操作

在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。

​ 即:先&=~();|=();

posted @ 2020-12-07 16:41  啊振不坏  阅读(209)  评论(0)    收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css