&= 和 |=

在嵌入式系统或底层编程中,&=|= 是非常常见的位操作运算符,用于对寄存器或变量的特定位进行精确控制,而不影响其他位。它们分别对应“清零某些位”和“置位某些位”的操作。


一、&= 的用途:清除某些位(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 对应的位设为 0P2DIR &= ~0x04;第 2 位清零(输入)
设置某些位|= mask把 mask 对应的位设为 1P2DIR |= 0x04;第 2 位置 1(输出)
保持其他位不变——精确控制——安全修改寄存器

四、为什么不能直接赋值?比如 P2DIR = 0x01;

直接赋值会改变所有位,可能意外关闭其他引脚的配置,造成 bug。使用 &=|= 可以做到:

  • 原子性修改:只改关心的位
  • 线程/中断安全:避免读-改-写竞争(在某些架构中仍需注意)
  • 代码可读性强:明确表达“设置”或“清除”的意图

五、实用技巧记忆口诀

  • |= 是“开”:想打开某个功能,就用 |= mask
  • &= 是“关”:想关闭某个功能,就用 &= ~mask

类比:| 像开关打开(有电),& 像开关关闭(必须都通才通)


六、扩展:同时设置和清除(更复杂操作)

有时需要同时设置和清除不同位,可以用:

P2DIR = (P2DIR & ~0xC0) | 0x40;  // 清除 bit7,设置 bit6

这表示:先把 bit7 和 bit6 清零,然后只把 bit6 置 1。


总结:

场景使用操作
把某些位设为 1(输出、使能)|= mask
把某些位设为 0(输入、禁用)&= ~mask
安全修改寄存器避免直接赋值,优先使用 &=|=

掌握这两个操作是嵌入式开发的基础技能!

发表评论