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

&& ではなく & を使用します。&& は論理 AND ですが、& はビット単位の AND です。

于 2010-09-08T18:53:11.173 に答える
3

あなたの解決策はほぼそこにありますが、いくつかの問題があります:

  • クロックがハイになると、クロックが再びローになる前にデータをバーストで送り出すため、クロックがローになっていることを確認する前に、クロックがハイになっている間一時停止する必要があります(ハードウェアがクロックがローになるまで実行を一時停止しない限り) )。これは、ループの最後または最初のいずれかで実行できます。以下のサンプルの最初の部分を選択しました。これは、クロックがまだ高いときに関数から戻り、まだ高いときに何らかの処理を実行できるためです。
  • 他の人が指摘しているように、ビット単位のand(&)の代わりに論理積(&&)を使用しました
  • 私はあなたのアーキテクチャに精通していないので、DataPinが0または1しか受け入れられないかどうかはわかりません。しかし、それは問題が発生する可能性があるもう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;
    }
}

while ... Bit++:目的を明確にするために、パターンの代わりにforループを使用しました。

于 2010-09-08T19:08:03.657 に答える
1

ある演算子を同様の機能を持つ別の演算子に置き換えたタイプミスがあります。つまり、&&両方のオペランドが論理的に true の場合、答え 1 を生成することが保証されます。ほとんどDataの場合、0 以外でテストしているため、これはループの 8 回の反復すべてに当てはまります。

これは、より微妙な問題を隠している可能性があります。ターゲットアーキテクチャが何であるかはわかりませんが、DataPin実質的に1ビット幅のレジスタである場合、0または1以外の値を割り当てないように注意する必要があります. それを達成する1つの方法は、書くことDataPin = !!(Data & Mask);です。もう 1 つは、データを逆方向にシフトし、1 の固定マスクを使用することです。

于 2010-09-08T18:56:39.177 に答える