我正在用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通用输入引脚,因为在这个引脚上我有一个脉冲红外传感器。它在闪烁时给我1,在休眠时给我0。
当P3^3上拉到1时,输出为(如预期的) 10101010101010..
当它仍然为0时,输出为(如不预期的) 0000000000000..
我得到的行为是我上面描述的,考虑到sbit X是由PIR设置/取消设置的。
所以问题是,在Keil C51编译器中,运算符!的含义是什么?
发布于 2013-06-19 03:12:11
在Keil C51中,引用manual
SFR类型在(特殊功能寄存器)内定义位(
)
因此,您并不是在循环之前声明变量X并读取它一次,而是定义了对P3.3的引用,并在每次循环迭代时读取它的状态。也就是说,X是对硬件I/O引脚寄存器的引用,而不是变量。
尽管表面上看起来,sbit不是一个简单的typedef别名,^也不是一个按位异或运算符。相反,它定义了对位可寻址寄存器的引用。将X写入分配给硬件寄存器-在这种情况下,行为由硬件定义,而不是语言。当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-19 02:41:38
大概它在标准C中的含义是相同的。如果为x==0,则!x的计算结果为1,否则为0。结果的类型为int。
如果您正在寻找可反转所有位的逐位补码,则需要~运算符。
更新:
除此之外,还有更多内容;请参阅Clifford's answer。
https://stackoverflow.com/questions/17176147
复制相似问题