我对位掩码感到困惑

时间:2019-05-12 10:14:40

标签: c bitmask iar

我正在使用IAR嵌入式工作台和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();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

@ L.F。注意到,^不是幂运算符,a <<是按位移位运算符,可以解决问题。

答案 1 :(得分:0)

此处mask是始终包含“ 2的幂”值的变量。 目标是始终在mask中仅设置一位。 mask用于测试“隔离”中的每个位。

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

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

让我们看一下程序运行时的一些实际值(假设8位)。 因此,在for循环中,mask的值随时间变化如下:

00000001
00000010
00000100
00001000
00010000
...

注意:例如,如果接收方想先看到最高位,最后要看到最低位,则也可以相反。不知道这里需要什么,只是您知道。 如果要反向执行,请用mask初始化(1 << (num_bits-1)),然后每次在循环本身mask >>= 1中向右移一步。

每个掩码值都是按AND位(&运算符)进行编辑的,输入值为signal,以“过滤”出我们感兴趣的特定位。

请记住:此AND操作的结果仍然是多个位-而不是单个位,因此我们无法寻找值1(我们还必须测试情况2, 4,8 ...等。

示例,假设所有位都打开,那么逻辑AND输出将如下所示:

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),这加剧了整个混乱。