7

当我看到这个时,我正在研究这个 ITE8712 看门狗定时器演示代码:

void InitWD(char cSetWatchDogUnit, char cSetTriggerSignal)
{
OpenIoConfig();     //open super IO of configuration for Super I/O

SelectIoDevice(0x07);   //select device7

//set watch dog counter of unit
WriteIoCR(0x72, cSetWatchDogUnit|cSetTriggerSignal);

//CloseIoConfig();      //close super IO of configuration for Super I/O
}

而且,我想知道这条线是什么意思:

cSetWatchDogUnit|cSetTriggerSignal

因为 WriteIoCR 函数看起来像这样:

void WriteIoCR(char cIndex, char cData)
{
//super IO of index port for Super I/O
//select super IO of index register for Super I/O
outportb(equIndexPort,cIndex);

//super IO of data for Super I/O
//write data to data register
outportb(equDataPort,cData);
}

所以cIndex应该是0x72,但是cData呢?我真的不明白“|” 因为我只在条件语句中将它用于 OR ("||")。

4

5 回答 5

14

它是按位的or,与您的正常逻辑不同or。如果设置了任一源变量中的相应位,则它基本上设置目标变量中的位。

例如,表达式43 | 17可以计算为:

43 = 0x2b = binary 0010 1011
17 = 0x11 = binary 0001 0001
                   ==== ====
        "or" them: 0011 1011 = 0x3b = 59

有关各种按位运算符的更彻底检查,请参阅此答案。

当您想要操作数据类型中的特定位时,通常使用它,例如控制嵌入式系统中的看门狗定时器(您的特定用例)。

您可以使用or (|)来打开和and (&)关闭它们(使用反转用于打开它们的位掩码。

因此,要打开该b3位,请使用:

val = val | 0x08; // 0000 1000

要关闭它,请使用:

val = val & 0xf7; // 1111 0111

要检测b3当前是否已设置,请使用:

if ((val & 0x08) != 0) {
    // it is set.
}

您通常会看到位掩码定义如下:

#define B0 0x01
#define B1 0x02
#define B2 0x04
#define B3 0x08
#define B4 0x10

或者:

enum BitMask {
    B0 = 0x01,
    B1 = 0x02,
    B2 = 0x04,
    B3 = 0x08,
    B4 = 0x10
};

至于这意味着什么:

WriteIoCR (0x72, cSetWatchDogUnit|cSetTriggerSignal);

很可能,0x72将是您正在写入的某种 I/O 端口,cSetWatchDogUnit并且cSetTriggerSignal将是您组合以输出命令的位掩码(设置触发信号并使用看门狗的单位值)。可以推断该命令在实践中的含义,但您更安全地参考看门狗电路本身的文档。

而且,如果您不知道看门狗电路的用途,这是一个简单的电路,如果您不经常启动它(使用另一个命令),它将重置您的系统,可能通过激活在您使用的任何处理器上重置引脚。

这是一种自动检测行为不良的软件并将设备返回到已知初始状态的方法,它遵循这样的理论,即重新启动比继续不良执行要好。

于 2011-05-23T04:36:18.493 回答
8

这是一个按位或。它在这里用于组合标志。

于 2011-05-23T04:35:06.960 回答
1

x | y通常与 C/C++ 中的普通旧数据一起使用。这意味着按位 OR

例如

char x = 0x1, y = 0x2;
x | y ==> 0x3

[注:operator |class/struct根据需要重载。]

于 2011-05-23T04:37:10.563 回答
1

|按位或。如果任一整数中相同位的一个或另一个打开,它将切换位(1 而不是 0)。

||逻辑或。如果一个或另一个为真,则返回真。

于 2011-05-23T04:38:12.250 回答
0

好的,这就是为什么您在这种情况下使用按位或或查看它们的原因。

通常,这些变量是用于将多条数据打包成一个字符的标志

如果cSetWatchDogUnitcSetTriggerSignal

有不重叠的位(想象一下cSetWatchDogUnit = 1 << 0cSetTriggerSignal = 1 << 1你可以稍后检查它们是否是按位设置的,就像这个人为的例子:

if cData & cSetWatchDogUnit
    do something
if cData & cSetTriggerSignal
    do something else

一直以来,这两个标志都可以打包到一个字符中并在其中传递。这样,您最终不会传递一个布尔数组,您可以添加新常量cSetSomeOtherDamnfoolThing = 1 << 2,并且可以在代码中将标志作为变量引用。

于 2011-05-23T04:39:41.177 回答