3

我正在尝试用 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 位。出于某种原因,我的输出引脚一直保持高电平。我确信端口引脚配置正确,所以这纯粹是一个逻辑问题。

4

3 回答 3

5

您想使用 &,而不是 &&。&& 是逻辑与,而 & 是按位与。

于 2010-09-08T18:53:11.173 回答
3

您的解决方案几乎就在那里,但有几个问题:

  • 当时钟变高时,您将在时钟有机会再次变低之前突然抽出数据,因此您需要在时钟为高时暂停,然后再检查它是否为低(除非硬件暂停执行直到时钟变低)。这可以在循环结束时完成,也可以在开始时完成。我在下面的示例中选择了开头,因为它允许您在时钟仍为高时从函数中返回,并在时钟仍为高时进行一些处理。
  • 正如其他人指出的那样,您使用了逻辑和 (&&) 而不是按位和 (&)
  • 我不熟悉你的架构,所以我不能说 DataPin 是否只能接受 0 或 1。但这也是可能出错的另一个点。Data & Mask 将返回一个左移的位(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++模式。

于 2010-09-08T19:08:03.657 回答
1

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

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

于 2010-09-08T18:56:39.177 回答