如何移出C中的位?

时间:2010-09-08 18:50:59

标签: c bit-shift

我正在尝试用C编写一个函数,它将根据时钟信号移出一个字节的各个位。到目前为止,我已经提出了这个......

void ShiftOutByte (char Data)
{
    int Mask = 1;
    int Bit = 0;
    while(Bit < 8)
    {
        while(ClkPin == LOW);
        DataPin = Data && Mask;
        Mask = Mask * 2;
        Bit++;
    }
}

其中DataPin表示我要将数据移出的端口引脚,而ClkPin是时钟端口引脚。

我希望器件从字节的LSB开始移出8位。出于某种原因,我的输出引脚始终保持高电平。我确信端口引脚配置正确,所以这纯粹是一个逻辑问题。

3 个答案:

答案 0 :(得分:5)

你想使用&amp;,而不是&amp;&amp;。 &安培;&安培;是合乎逻辑的,而且&amp; amp;是按位和。

答案 1 :(得分:3)

你的解决方案几乎就在那里,但有一些问题:

  • 当时钟变为高电平时,您将在时钟有可能再次变为低电平之前以突发方式输出数据,因此您需要在时钟为高电平时暂停,然后再检查它是否为低电平(除非硬件暂停执行直到时钟变低了)。这可以在循环结束时或开始时完成。我在下面的示例中选择了开头,因为它允许您在时钟仍然很高时从函数返回,并在它仍然很高时进行一些处理。
  • 您使用了逻辑和(&amp;&amp;)代替按位和(&amp;),正如其他人指出的那样
  • 我不熟悉你的架构,所以我不能说DataPin是否只能接受0或1.但这也是事情可能出错的另一点。数据&amp;掩码将返回一个向左移位的位(1,2,4,8,...),具体取决于位的位置。

因此,总而言之,我会做类似的事情:

void ShiftOutByte (unsigned char Data)
{
    int Bit;
    for(Bit=0; Bit < 8; ++Bit)
    {
        while(ClkPin == HIGH);
        while(ClkPin == LOW);
        DataPin = Data & 1;
        Data >>= 1;
    }
}

注意:为了清晰起见,我使用了for循环而不是while ... Bit++模式。

答案 2 :(得分:1)

您有一个拼写错误,它已将一个运算符替换为另一个具有类似功能的运算符。也就是说,如果&&的两个操作数都是逻辑真的,则Data保证产生答案1。由于您几乎肯定在DataPin测试时不是零,所以循环的所有八次迭代就是这种情况。

这可能掩盖了一个更微妙的问题。我不知道您的目标架构是什么,但如果DataPin = !!(Data & Mask);实际上是一位宽的寄存器,那么您可能需要小心不要尝试为其分配0或1以外的值。实现这一目标的一种方法是编写{{1}}。另一种方法是将数据移向另一个方向,并使用固定的掩码1。