在嵌入式系统或底层编程中,&=
和 |=
是非常常见的位操作运算符,用于对寄存器或变量的特定位进行精确控制,而不影响其他位。它们分别对应“清零某些位”和“置位某些位”的操作。
一、&=
的用途:清除某些位(Clear bits)
语法:variable &= ~mask;
~mask
表示对掩码取反。&=
与操作:只有当两个位都为 1 时结果才为 1。- 所以,
&= ~mask
的作用是:把 mask 中为 1 的那些位清零,其余位保持不变。
✅ 典型用途:
- 将某个引脚设置为输入模式(DIR 寄存器清零)
- 关闭某个中断使能位
- 清除状态标志位
📌 例子:
P2DIR &= ~0xc0; // 0xc0 = 0b11000000
~0xc0
=0b00111111
- 结果:P2DIR 的第 6 位和第 7 位被清零(设置为输入),其他位不变。
二、|=
的用途:设置某些位(Set bits)
语法:variable |= mask;
|=
或操作:只要有一个为 1,结果就是 1。- 所以,
|= mask
的作用是:把 mask 中为 1 的那些位置 1,其余位保持不变。
✅ 典型用途:
- 将某个引脚设置为输出模式
- 使能某个中断或功能
- 设置控制标志
📌 例子:
P2DIR |= 0x01; // 0x01 = 0b00000001
- 结果:P2DIR 的第 0 位被置 1(设置为输出),其他位不变。
三、对比总结
操作 | 运算符 | 目的 | 例子 | 效果 |
---|---|---|---|---|
清零某些位 | &= ~mask | 把 mask 对应的位设为 0 | P2DIR &= ~0x04; | 第 2 位清零(输入) |
设置某些位 | |= mask | 把 mask 对应的位设为 1 | P2DIR |= 0x04; | 第 2 位置 1(输出) |
保持其他位不变 | —— | 精确控制 | —— | 安全修改寄存器 |
四、为什么不能直接赋值?比如 P2DIR = 0x01;
直接赋值会改变所有位,可能意外关闭其他引脚的配置,造成 bug。使用 &=
和 |=
可以做到:
- 原子性修改:只改关心的位
- 线程/中断安全:避免读-改-写竞争(在某些架构中仍需注意)
- 代码可读性强:明确表达“设置”或“清除”的意图
五、实用技巧记忆口诀
|=
是“开”:想打开某个功能,就用|= mask
&=
是“关”:想关闭某个功能,就用&= ~mask
类比:
|
像开关打开(有电),&
像开关关闭(必须都通才通)
六、扩展:同时设置和清除(更复杂操作)
有时需要同时设置和清除不同位,可以用:
P2DIR = (P2DIR & ~0xC0) | 0x40; // 清除 bit7,设置 bit6
这表示:先把 bit7 和 bit6 清零,然后只把 bit6 置 1。
✅ 总结:
场景 | 使用操作 |
---|---|
把某些位设为 1(输出、使能) | |= mask |
把某些位设为 0(输入、禁用) | &= ~mask |
安全修改寄存器 | 避免直接赋值,优先使用 &= 和 |= |
掌握这两个操作是嵌入式开发的基础技能!