LIFE LOG(ここにはあなたのブログ名)

作業日誌 う靴

気ままにコンピュータ関連の備忘録などを書きます...。

あの格安FPGAボードで 7セグメントLED をドライブする~Part.3

1. はじめに

 今回は、前回Part.2に引き続いて、ストップウォッチ完成に向けた制作を進めました。具体的には、7セグメントLEDの桁数を2ケタに増設し、それぞれのケタを交互に高速点滅させることによって、人の目の残像効果を利用し、連続的に点灯しているかのように見せるダイナミック・ドライブというテクニックを使い実装しました。

2. 実験回路

 NPN型汎用トランジスタ(2SC1815)のベースに微弱電流(0.3mA程度?)を流し、それを増幅して、なおかつコレクタ-エミッタ間を5ms毎に高速?スイッチングすることで、1ケタ目と2ケタ目の7セグメントLEDへの出力を高速に切り換え、ダイナミック点灯するようにした。なお、OUT(PINxx)はFPGAボードの各種ピンに接続しており、OUTPUTに設定している。

 ※OUTPUTピンの電流量はQuartus上のピンアサインの設定のところで変えられる。そのため、電流制限抵抗は挟んでいない。挟むのがベターと思うけれど。適宜、7セグLEDを光らせるのに適した設定値にしてください。

http://akizukidenshi.com/catalog/g/gI-04268/akizukidenshi.com

akizukidenshi.com

3. VHDLコード(全文)

 このコードで動作確認した。野暮ったい書き方のところがあるかもしれないが、動くことを第一優先に。

CNT60.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity CNT60 is
port(   CLK         :     in  std_logic;
        SEG7LED1 :     out std_logic_vector ( 7 downto 0 );
        TR1, TR2   :   out std_logic  );
end CNT60;


architecture RTL of CNT60 is
signal SIX:  std_logic_vector ( 2 downto 0 );
signal DEC:  std_logic_vector ( 3 downto 0 );
signal CRY, T1S : std_logic;
signal CNT:  integer range 0 to 24999999*2;  --1000ms分確保
signal CNT_SW:  integer range 0 to 249999;   -- 5ms分確保
signal TR1_SW, TR2_SW: std_logic;

begin

    process(CRY)
    begin
        if(CRY'event and CRY = '1') then
            if( SIX = "101") then
                SIX <= "000";
            else
                SIX <= SIX + 1;
            end if;
        end if;
    end process;
    
    
    process(T1S)
    begin
        if( T1S'event and T1S = '1') then
            if( DEC = "1001" ) then
                DEC <= "0000";
                CRY <= '1';
            else
                DEC <= DEC + 1;
                CRY <= '0';
            end if;
        end if;
    end process;
    
    
    process( CLK )
    begin
        if( CLK'event and CLK = '1') then
            if( CNT = 24999999*2 ) then
                T1S <= '1';
                CNT <= 0;
            else
                CNT <= CNT + 1;
                T1S <= '0';
            end if;
        end if;
    end process;
    
    
    process( CLK )
    begin
       if( CLK'event and CLK = '1') then
           if( CNT_SW < 250000/2 ) then
                TR1_SW <= '1';
                TR2_SW <= '0';
                CNT_SW <= CNT_SW + 1;
            elsif( 250000/2 <= CNT_SW and CNT_SW < 250000) then 
               TR1_SW <= '0';
                TR2_SW <= '1';
                CNT_SW <= CNT_SW + 1;
            else
               TR1_SW <= '0';
                TR2_SW <= '0';
                CNT_SW <= 0;
            end if;
        end if;
    end process;
    
    
    process(DEC, SIX, TR1_SW, TR2_SW)
    begin
        if(TR1_SW = '1' and TR2_SW = '0') then
            TR1 <= '0';
            TR2 <= '1';
            case SIX is
                when "000" => SEG7LED1 <= not "00000011";  --0
                when "001" => SEG7LED1 <= not "10011111";  --1
                when "010" => SEG7LED1 <= not "00100101" ; --2
                when "011" => SEG7LED1 <= not "00001101" ; --3
                when "100" => SEG7LED1 <= not "10011001";  --4
                when others => SEG7LED1 <= not "01001001"; --5
            end case;
     
        elsif(TR1_SW = '0' and TR2_SW = '1') then
            TR1 <= '1';
            TR2 <= '0';
            case DEC is
                when "0000" => SEG7LED1 <= not "00000011";  --0
                when "0001" => SEG7LED1 <= not "10011111";  --1
                when "0010" => SEG7LED1 <= not "00100101";  --2
                when "0011" => SEG7LED1 <= not "00001101";  --3
                when "0100" => SEG7LED1 <= not "10011001";  --4
                when "0101" => SEG7LED1 <= not "01001001";  --5
                when "0110" => SEG7LED1 <= not "01000001";  --6
                when "0111" => SEG7LED1 <= not "00011011";  --7
                when "1000" => SEG7LED1 <= not "00000001";  --8
                when others => SEG7LED1 <= not "00001001";  --9
            end case;
        else
           TR1 <= '0';
           TR2 <= '0';
        
        end if;
    end process;
    
end RTL;

4. 実験結果

 こんな感じで、60秒まで計れるストップウォッチぽくなってきました。次回はいよいよ完成するか...??

www.youtube.com

5. 参考文献

7セグメントLED | マルツオンライン

トランジスタ(NPN)の使い方 [Arduino]