我对位掩码感到困惑

I'm confused with bitmasks

我正在使用 IAR 嵌入式 workbench 和 C。我想创建一个掩码并决定传输的下一位是 1 还是 0。

我试过了但是没用

int transmit(int signal, int number_of_bits)
{

    int mask;
    for (int i = 0; i < number_of_bits; i++)
    {
        mask = pow(2,number_of_bits-1-i)
        if ((signal & mask) == 0) // bit '0'
        {
            transmit0();
        }
        else // bit '1'
        {
            transmit1();
        }
    }
}

我试过了,它传输 0001,但我正在尝试传输 1000(反之亦然)

int transmit(int signal, int number_of_bits)
{

    int mask;
    for (int i = 0; i < number_of_bits; i++)
    {
        mask = (1 << i);
        if ((signal & mask) == 0) // bit '0'
        {
            transmit0();
        }
        else // bit '1'
        {
            transmit1();
        }
    }
}

正如@L.F 注意到的那样,^ 不是幂运算符,唉 <<,位移运算符,可以解决问题。

此处 mask 是将始终包含 "power of 2" 值的变量。 目标是始终只在 mask 中设置一位。 这个mask用来测试"isolation"中的每一位。

结合逻辑 AND 函数,您可以将其视为一个过滤器,它只为您提供特定位对应的值或不提供任何值(零)。

请记住,根据定义,仅设置一位的二进制字的值始终对应于 2 的幂值。因此,在测试单个位之后,您将看到零或 2 的幂值。

让我们在程序运行(假设8位)的情况下看一些实际值。 所以在 for 循环中,这就是 mask 的值随时间变化的样子:

00000001
00000010
00000100
00001000
00010000
...

注意:您也可以进入相反的方向,例如,如果接收方希望先看到最高位,最后看到最低位。不知道这里需要什么,但只是让你知道。 如果你想倒退,你用 (1 << (num_bits-1)) 初始化 mask 然后在循环中每次向右走一步 mask >>= 1).

每个掩码值都是按位 AND-ed(& 运算符),输入值 signal 到 "filter" 是我们感兴趣的特定位.

记住:这个 AND 操作的结果仍然是多位——而不是一位,所以我们不能寻找 1 的值(我们还必须测试案例2、4、8 ...等等)。

例如,假设所有位都打开,则逻辑与输出将如下所示:

00000001 AND 11111111 = 00000001
00000010 AND 11111111 = 00000010
00000100 AND 11111111 = 00000100
00001000 AND 11111111 = 00001000
00010000 AND 11111111 = 00010000
...

请注意在这种情况下结果如何遵循掩码。 尽管每次的值都不同,但您知道当您得到非零值时,您测试的位一定很高!

如果所有位都关闭,您将看到:

00000001 AND 00000000 = 00000000
00000010 AND 00000000 = 00000000
00000100 AND 00000000 = 00000000
00001000 AND 00000000 = 00000000
00010000 AND 00000000 = 00000000

您会注意到检查结果是否为零更容易。这意味着该位已关闭。这也是代码只检查零值的原因,它知道在所有其他情况下该位是 1

现在的诀窍是获取正确的掩码值。 你想要的是将 1 的位值向左移动到正确的位置。 因此,如果您开始测试位 4,例如,您将 1 向左移动四位,您将得到(00010000 二进制)。

为此,我们使用左移运算符 <<

正如其他人已经说过的,^ 不幸地做了一些完全不同的事情 (XOR),这增加了整个混乱。