■シリアルA/Dからのデータ入力

 A/D変換を行う場合、端子数の低減や小型化でシリアル出力型のA/D変換素子を使うことが多いと思います。
しかし、データの同期やコマンドの転送などインターフェースの手間が増えることも事実です。そこで、CPLDにA/D変換とのインターフェースをませてしまう方法をここでは示します。

AD7495のデータシート(アナログデバイセス)

■動作説明とレジスタ表

用意するレジスタを示します。このA/DはSCLKと同期したタイミングでデータを出すのでSCLKを用意します。カタログデータからSCLKは、10kHz〜20MHzになっているのでこの間で設定します。
また、CSがLOWでA/Dがアクティブになりますので、この信号ラインも必要です。今回はわかりよい様にCall_adとしました。

動作は、
@Call_adをたち下げ、A/Dコンバータの変換を開始する。
Aデータを16bit入力するまで、bufのLSBにSDATAからのビットをビットシフトしながら追加。
B16bit読み終わったらStrageへ保管

という形で動いています。Bのタイミングで内部フラグbusy_adをたち下げていますので、もし外部のCPUから読み込むならばこの信号を出力し立下りのタイミングでデータをCPU側に読み込むと言う方法もあります。

緒言 レジスタ名 タイプ名 説明
入力I/O  clk: in std_logic; メインクロックです。シリアルA/Dの動作周波数にあわせます。 
SDATA: in std_logic; シリアルA/Dからの入力データです。 
出力I/O  out: out std_logic_vector(11 downto 0); パラレルデータとして出力します。 
sclk: out std_logic; シリアルA/Dとの同期クロックを出力します。 
call_ad: out std_logic; シリアルA/Dの変換を開始します。 
コントロールフラグ  busy_ad: std_logic; A/D処理中を示す。
buf: std_logic_vecter(11 downto 0); A/Dからの信号を保持する。
strage: std_logic_vector(11 downto 0); 読み込んだデータを一時保管する。 
内部レジスタ  ad_count: std_logic_vector(4 downto 0); A/Dプロセスのステップを管理する。 

■VHDLソース

VHDLソースを示します。
VHDLソース
entity test is
    Port ( 
        clk:            in      std_logic;
        sdata:          in      std_logic;
        data:           out     std_logic_vector(11 downto 0);
        sclk:           out     std_logic;
        call_ad:        out     std_logic
        );
end test;

architecture Behavioral of test is

signal busy_ad:         std_logic;
signal ad_count:        std_logic_vector( 4 downto 0);
signal storage:         std_logic_vector(11 downto 0);
signal buf:             std_logic_vector(11 downto 0);

begin
data <= storage;
sclk <= not(clk);
------------------------------------------------------
--使用するプロセス内に、ここの部分を入れてください。
------------------------------------------------------

        cls_ad  <= '1';

        if fin_ad='0' and busy_ad = '0' then
        call_data <= '1';
        cls_ad ,= '0';
        end if;

        if fin_ad='1' then
        flag <='1';--逐次的に処理がしたい場合は、
             --フラッグを使用して処理をとばさないようにする。
        end if;


-----------------------
--シリアルA/Dからの読み込み
-----------------------
process (CLK)           
begin
if  clk'event and clk='1' then
        if cls_ad = '1' then
        fin_ad <= '0';
        end if;

        if call_data='1' then
                if busy_ad='0' then
                busy_ad <='1';
                call_ad <='0';
                end if;
        end if;

        if ad_count /= 16 then
        ad_count <= ad_count + 1;
        end if;

        if busy_ad='1' and ad_count <15 then
        buf <= buf(10 downto 0) & sdata;
        end if;

        if ad_count>=15 then
                call_ad         <='1';
                busy_ad         <= '0';
                ad_count        <= "00000";
                storage <= buf;
        end if;
end if;
end process;
end Behavioral;

Copyright (C) 錬金術師Masa
初版:2004年8月26日
更新:2005年8月07日
http://www.katch.ne.jp/~mh_524-1997/