3

我正在使用 Keil uVision 4 进行编程。

我有一些这样的代码:

sbit X = P3 ^ 3; // X is third bit of P3 register

...

    while (1) {
      X = !X; // X equals not X ?!

      if (X == 0)
        printf("0");
      else
        printf("1");
    }

我可以控制`P3^3通用输入引脚,因为在这个引脚上我有一个 PIR(脉冲红外传感器)。它在闪烁时给我 1 在那条线上,在它睡觉时给我 0。

P3^3被上拉到 时1,输出为(如预期的那样)10101010101010..

当它仍然为0时,输出为(如预期的那样)0000000000000..

我得到的行为是我上面描述的,考虑到这sbit X是由 PIR 设置/取消设置的。

那么问题来了,!Keil C51编译器中的操作符是什么意思呢?

4

2 回答 2

4

在 Keil C51 中,引用手册

sbit 类型特殊功能寄存器 (SFR)中定义一个位

因此,您不是在声明变量 X 并在循环之前读取它一次,而是定义对 P3.3 的引用,并在循环的每次迭代中读取它的状态。也就是说X是对硬件I/O引脚寄存器的引用,而不是变量。

尽管外表sbit不是一个简单的typedef别名,^也不是按位异或运算符。相反,它定义了对位可寻址寄存器的引用。将写入分配X给硬件寄存器 - 在这种情况下,行为由硬件而不是语言定义。当外部拉高时明显改变 X 值的能力,我猜这是 GPIO 硬件的本质,而不是!操作员的任何奇怪行为。检查硬件文档以了解 I/O 引脚行为,但我再次猜测将其拉高会使引脚能够输出

为了得到你期望的行为(我想),你会这样编码:

sbit p = P3 ^ 3; // p is third bit of P3 register


...
int X = p ; // get p's current value

while (1) {
  X = !X; // X equals not X ?!

  if (X == 0)
    printf("0");
  else
    printf("1");
}
于 2013-06-18T19:12:10.737 回答
0

据推测,它的含义与标准 C 中的含义相同。!x评估为1ifx==00其他。结果是类型int

如果您正在寻找反转所有位的按位补码,则需要~运算符。

更新 :

不止于此;见克利福德的回答

于 2013-06-18T18:41:38.343 回答