あの格安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
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秒まで計れるストップウォッチぽくなってきました。次回はいよいよ完成するか...??