SSブログ

Smart I/O でワンショットパルスを作る [PSoC]このエントリーを含むはてなブックマーク#

回路図

貧弱な PSoC 4000S でワンショットパルスを出したい。 こういう要望があったので、 Smart I/O で実現してみました。 与えたクロック数発分のパルスをソフトウェアでトリガします。

このプロジェクトは、 CY8CKIT-145-40XX PSoC 4000S Prototyping Kit で動作させています。

大まかな動作原理

Smart I/O の設定

Smart I/O の内部は、このように構成してみました。 ソフトウェアのトリガは、 data4 から LUT5 に入り、立ち上がりが検出されます。 立ち上がりが検出されると LUT4 のステートマシンが動作を始めます。 LUT4 は、 LUT6 を介して、 Data Unit (DU) のダウンカウンタを起動します。 カウンタがゼロになったら、 LUT4 に通知し、カウンタもリセットされます。

コントロールレジスタは無いけれど

ソフトウェアでトリガをかけるためには、 PSoC 5LP でいうところの Control Register のようなものが必要です。 ところが、貧弱な PSoC 4000S には UDB が搭載されていません。 そこで、 Control Register にかわる代替案を持ってきました。

トップレベル回路図を見るとわかりますが、 data4 という入力端子が浮いたままになっています。 ここには、 TCPWM などのペリフェラルを接続するのが通常の使い方なのですが、 data4 の入力設定はあえて "Undefined" にしてあります。 こうすると、 data4 には、ある信号が入ってきます。 それは、 gpio4 に接続されている Pin_3_4 端子のデータレジスタです。

Pin_3_4 端子の出力は、 Smart I/O に接続されているので、データレジスタは用がありません。 この用のないデータレジスタが、故意なのか偶然なのか data4 入力に自動的に接続されてしまうのです。 そのため、 data4 を操作したかったら、 Pin_3_4_Write() 関数で論理を指定できます。 これは、便利。

立ち上がり検出

立ち上がり検出

data4 から入ってきた信号は、 LUT5 を使って立ち上がりを検出します。 これには、エッジ検出に使ってくれと言わんばかりの "Registered input" というモードを使います。 input2 にだけフリップフロップが付いているので、クロックの前後で信号が変化した事を検出することができます。

メインのステートマシン

メインのステートマシン

LUT4 は、パルスを出力するステートマシンです。 まあ、ステートマシンと言っても、たったの2状態ですが。 ステートマシンの攻勢は単純です。 出力が 0 の時に LUT5 にパルスが入ったら、出力を 1 に変化させます。 また、出力が 1 の時に DU にパルスが入ったら、出力を 0 に変化させます。

LUT5 は、立ち上がり検出で作られたパルス出力の開始を示す信号です。 また、 DU は、 Data Unit が出力するカウンタがゼロになった事を示す信号です。 これら2つの信号により、カウント開始からカウンタがゼロになるまでの時間、出力を 1 にしてパルスを作成します。

リセット論理

リセット論理

LUT6 は、 Data Unit のカウンタをリセットするための信号を作る組み合わせ論理です。 カウンタは、 LUT4 の出力が 0 の間はリセットされます。 また、カウンタがゼロになって DU が出力された次のサイクルでもリセットされます。 これら2つのリセット条件を持たせているのが LUT6 です。

この LUT は、組み合わせ論理回路になっていますが、これは、カウンタのリセット入力が同期リセットであるためです。

ダウンカウンタ

ダウンカウンタ

ダウンカウンタは、 DU_reg で決められた値からゼロまでカウントを行います。 このため、 LUT4 が出力パルスの幅は、 DU_reg に設定した数よりもひとつ多くなります。 ここでは、 0x05 を設定しているので、6クロックのパルスが生成されることになります。

トップレベル回路図

トップレベル回路図

この Smart I/O ブロックには、 data0 からクロックを与えているのですが、そのクロック源は PWM による 1Hz のクロックです。 1Hz で動作してくれるので、目でデバッグできます。

実際に使用する際には、適宜クロックを与えます。 また、 gpio5 と gpio6 は、デバッグのために出力させているため、必須ではありません。

ソフトウェア

ソフトウェア

テストソフトウェアは、 Pin_3_4_Write() 関数で data4 をトリガしているだけです。 LUT5 を使って立ち上がり検出をしているので、トリガパルスは、クロック周期よりも長くする必要があります。 そのため、 Pin_3_4_Write(1) と Pin_3_4_Write(0) の間にソフトウェアディレイを入れてあります。 クロックの周波数がもっと速ければ、ディレイは必要ないでしょう。

int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    PWM_1Hz_Start();
    SmartIO_P3_Start();

    for(;;)
    {
        /* Place your application code here. */
        Pin_3_4_Write(1u);
        CyDelay(1500);
        Pin_3_4_Write(0u);
        CyDelay(10000);
    }
}

プロジェクトアーカイブ

この記事で作成したプロジェクトは、このファイルの拡張子を "zip" に変更すると再現できます。


nice!(0)  コメント(0)  このエントリーを含むはてなブックマーク#