0

仲間の SO ユーザー、

抵抗湿度センサーを 5 Hz (1 秒あたり 5 サンプル) の頻度でサンプリングしようとしています。出力を読み取るためにADCを使用しています。現在、ADC は任意の周波数で実行できると言われていますが、変換を開始して ADC から値を読み取るには 5Hz クロックを使用する必要があります。

私がこれを行っている方法は、5hz で実行し、クロックの立ち上がりエッジで「start_convert」を「1」にするフラグを持つことによって変換を開始するプロセスを持つことです。

PROCESS (CLK_5HZ)       
BEGIN
    IF (CLK_5HZ'EVENT AND CLK_5HZ = '1') THEN
        START_CONVERT <= '1';
    END IF;
END PROCESS;

そして、ADC 用のステート マシンがあります。

PROCESS (CURR_STATE, INTR)
                BEGIN

                CASE CURR_STATE IS

                        WHEN STARTUP =>
                            WR <= '0';
                            READ_DATA <= '0';
                            IF (START_CONVERT = '1') THEN
                                NEXT_STATE <= CONVERT;
                            ELSE
                                NEXT_STATE <= STARTUP;
                            END IF;

                        WHEN CONVERT =>
                            IF (INTR = '0' AND STREAM = '1') THEN
                                NEXT_STATE <= WAIT500;
                            ELSIF (INTR = '0' AND STREAM = '0') THEN
                                NEXT_STATE <= READ1;
                            ELSE
                                NEXT_STATE <= CONVERT;
                            END IF;
                            WR <= '1';
                            READ_DATA <= '0';

                        WHEN WAIT10 =>
                            IF (COUNTER_WAIT = 10) THEN
                                NEXT_STATE <= READ1;
                            ELSE
                                NEXT_STATE <= WAIT10;
                            END IF;
                            COUNTER_WAIT <= COUNTER_WAIT + 1;

                        WHEN READ1 =>
                            NEXT_STATE <= CONVERT;
                            WR <= '1';
                            READ_DATA <= '1';

                        WHEN OTHERS =>
                            NEXT_STATE <= STARTUP;
                END CASE;
                END PROCESS;

そして、5hz で別のプロセスを使用して、READ_DATA が 1 であることを検出し、ADC から値を読み取っています。

PROCESS (CLK_5HZ, RST)
    BEGIN
    IF (RST = '1') THEN
    Y <= (OTHERS => '0');
    ELSIF (CLK_5HZ'EVENT AND CLK_5HZ = '1') THEN
        IF (READ_DATA = '1') THEN
        Y <= DATA_IN (0) & DATA_IN (1) &
         DATA_IN (2) & DATA_IN (3) &
         DATA_IN (4) & DATA_IN (5) &
         DATA_IN (6) & DATA_IN (7);
    END IF;
   END IF;
END PROCESS;

これが正しいアプローチであるかどうか、誰かにアドバイスしてもらえますか?

編集: Spartan-3 ボードを使用して ADC (ADC0804) に接続しています。

4

1 に答える 1

3

インターフェースしようとしているデバイスの詳細がわからない場合、具体的なアドバイスを与えるのは少し難しいです。

ただし、コードに関する一般的なコメントがいくつかあります。

  • 非同期プロセス(PROCESS (CURR_STATE, INTR))は、すべての場合にすべての信号を設定しているわけではないため、合成時にかなりの数のラッチを生成します。たとえば、あなたの州WRでは設定されていません。これはおそらく深刻なタイミングの問題につながるため、これを修正することは絶対にやりたいことです。READ_DATAWAIT10

  • 同じプロセスの状態は、更新さWAIT10れるたびに実行されるため、組み合わせループを提供します。COUNTER_WAITその状態も更新COUNTER_WAITされるため、理論的には実行を継続しますが、実際にはほとんどのシンセサイザーでエラーが発生します(私は思います)。代わりに、インクリメントを同期/クロックプロセスに移動する必要があります。これにより、各サイクルにかかる時間を制御することもできます。

  • 5 Hzのプロセスは別のクロックで実行されているようです(CLK_5HZ)。システムの残りの部分はより速いクロックで実行されていると思いますか?これにより、基本的に2つ(またはそれ以上)のクロックドメインが得られ、それらを相互にインターフェイスするための特別なインターフェイスロジックが必要になります。はるかに優れたソリューションは、すべてを同じ(高速)クロックで実行し、クロックイネーブルを使用して低速のプロセスを制御することです。したがって、すべてが本質的に同期されており、厄介なタイミングの驚きを与えることはありません。

于 2012-10-15T09:54:40.660 に答える