前言

由于在单片机编程中能够直接控制硬件,使得位运算能够提供更快的运算效率与端口处理能力。

位运算

运算符 含义
& 按位与
\ 按位或
^ 按位异或
~ 按位取反
<< 左移
>> 右移

a&b,当a与b均为1时结果为1,例如(负数以补码储存):

  • 1&2 = (0b 0001)&(0b 0010) = 0b 0000 = 0
  • -1&-2 =(0b 1111)&(0b 1110) = 0b 1110 = -2

    应用

  • &1——保留:1&1 = 1;0&1 = 0,与1相与能够保留原始位上的数据。
  • &0——清零:1&0 = 0;0&0 = 0,与0相与能够清除当前位上的数据。

a|b,当a与b有1时结果即为1。

应用

  • |0——保留:1|0 = 1;0|0 = 0,与0相或能够保留原始位上的数据。
  • |1——置1:1|1 =1;0|1 =1,与1相或能够将当前位置为1。

配合使用

  • 清零——a&0xfe:清除第零位,并保留其他位置
  • 检测/保留——a&0x01:检测第零位,并清零其他位
  • 检测/保留——a|0xfe:保留第零位,并将其他位置一
  • 仅修改第零位,而不改变其它七位:TMOD |= 0x01
  • 置零后修改第四位:P2=(P2&0X1f)|0X80;

异或

a^b,当a与b相同时为0,不同时为1,例如:0x48^0x2f = 0x67

应用

  • ^1——翻转:1^1 = 0;0^1 = 1。与1相异或能够将该位电平翻转。
  • ^0——检测/保留:0^0 = 0;1^0 = 1。与0相异或能够保留原位的数据。
  • 例如键盘扫描程序中read_data = P3^0xff:如果对应按键按下,该位置为1。

左移

注意左右移位时需要考虑变量类型,假设unsigned char类型:

  • 4<<2 = (0b 0000 0100)<<2 = 0b 0001 0000 = 16 //左移N位,相当于变量乘2N
  • 64<<2 = (0b 0100 0000)<<2 = 0b 0000 0000 = 0 //变量溢出,填充为0

右移

右移N位相当于除2N,Keil使用算数右移,因此在处理负数的时候会将移位填充1。

  • 32>>1 = (0b 0010 0000)>>1 = 0b 0001 0000 = 16
  • -32>>1 = (0b 1111 1110)>>1 = 0b 1111 1111 = -16