?? tlc549.vhd
字號:
--文件名:tlc549.vhd
--功 能:數字電壓表
--說 明:學習模數轉換芯片(tlc549)的使用
-- 通過修改競賽板上電位器的抽頭值可以達到修改當前電壓值的目的
-- 發光二極管上顯示的是模數轉換后的數字量
-- 數碼管上顯示的是當前電壓值
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tlc549 is
Port (clk : in std_logic; --50m系統時鐘
din : in std_logic; --(tlc549)串行數據輸出端
clk_tlc549 : out std_logic;
cs_tlc549 : out std_logic; --tlc549的片選信號輸入端
shift : out std_logic_vector(3 downto 0);--動態掃描時的位選信號
cs_led : out std_logic_vector(1 downto 0);--競賽板的發光二極管及數碼管的片選信號輸入端
dout_led : out std_logic_vector(7 downto 0));--競賽板的發光器件的信號輸出端
end tlc549;
architecture Behavioral of tlc549 is
type state is (st1,st2);
signal current_state : state;
type state1 is (st0,st1,st2);
signal current_state1 : state1;
type state2 is (st0,st1,st2,st3,st4);
signal current_state2 : state2;
signal reg_datain : std_logic_vector(7 downto 0);
signal reg_dout : std_logic_vector(15 downto 0);
signal dout : std_logic_vector(4 downto 0);
signal reg_din : integer range 0 to 80000;
signal clk1m,clk1k,clk100 : std_logic;
begin
--分頻部分
process(clk) --產生1MHz的頻率
variable cnt : integer range 0 to 50;
begin
if clk'event and clk='1' then cnt:=cnt+1;
if cnt<50 then
if cnt<25 then clk1m<='0';
else clk1m<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
process(clk1m) --產生1KHz的頻率
variable cnt : integer range 0 to 1000;
begin
if clk1m'event and clk1m='1' then cnt:=cnt+1;
if cnt<1000 then
if cnt<500 then clk1k<='0';
else clk1k<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
process(clk1k) --產生100Hz的頻率
variable cnt : integer range 0 to 10;
begin
if clk1k'event and clk1k='1' then cnt:=cnt+1;
if cnt<10 then
if cnt<5 then clk100<='0';
else clk100<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
--tlc549的控制部分
process(clk1k)
variable cnt : integer range 0 to 7;
variable datain : std_logic_vector(7 downto 0);
begin
if clk1k'event and clk1k='1' then
case current_state is
when st1=> --將數據進行串并轉換
cs_tlc549<='0';
datain:=datain(6 downto 0)&din; --將讀取的數據向高位移位
clk_tlc549<='1';
current_state<=st2;
when st2=>
cs_tlc549<='0';
clk_tlc549<='0';
current_state<=st1;
if cnt<7 then cnt:=cnt+1; --讀取8位數據
else cnt:=0;
reg_din<=conv_integer(datain)*195; --每單位數字量乘以系數=當前電壓值;
reg_datain<=not(datain);
end if;
when others=>
current_state<=st1;
end case;
end if;
end process;
--十進制-BCD碼轉換;
process(clk100)
variable reg : integer range 0 to 80000;
variable d1,d2,d3,d4 : std_logic_vector(3 downto 0);
begin
if clk100'event and clk100='1' then
case current_state1 is
when st0=>
reg:=reg_din;
d1:="0000";d2:="0000";d3:="0000";d4:="0000";
current_state1<=st1;
when st1=>
if reg>9999 then reg:=reg-10000;d1:=d1+1;
elsif reg>999 then reg:=reg-1000;d2:=d2+1;
elsif reg>99 then reg:=reg-100;d3:=d3+1;
elsif reg>9 then reg:=reg-10;d4:=d4+1;
else current_state1<=st2;
end if;
when st2=>
reg_dout<=d1&d2&d3&d4;
current_state1<=st0;
when others=>
current_state1<=st0;
end case;
end if;
end process;
--動態掃描控制;
process(clk1k)
begin
if clk1k'event and clk1k='1' then
case current_state2 is
when st0=> --在發光二極管上顯示模數轉換后的數字量
cs_led<="01"; --熄滅數碼管
shift<="1111";
dout<="11111";
current_state2<=st1;
when st1=> --在數碼管的最高位顯示數據
cs_led<="10"; --熄滅發光二極管
shift<="0111"; --最高位數碼管顯示
dout<='0'®_dout(15 downto 12); --小數點顯示,并且將最高位的數據送給譯碼器
current_state2<=st2;
when st2=> --在數碼管的次高位顯示數據
cs_led<="10"; --熄滅發光二極管
shift<="1011"; --次高位數碼管顯示
dout<='1'®_dout(11 downto 8); --小數點不顯示,將次高位的數據送給譯碼器
current_state2<=st3;
when st3=> --在數碼管的次低位顯示數據
cs_led<="10"; --熄滅發光二極管
shift<="1101"; --次低位數碼管顯示
dout<='1'®_dout(7 downto 4); --小數點不顯示,將次低位的數據送給譯碼器
current_state2<=st4;
when st4=> --在數碼管的最低位顯示數據
cs_led<="10"; --熄滅發光二極管
shift<="1110"; --最低位數碼管顯示
dout<='1'®_dout(3 downto 0); --小數點不顯示,將最低位的數據送給譯碼器
current_state2<=st0;
when others=>
current_state2<=st0;
end case;
end if;
end process;
--**將BCD碼進行8段譯碼(包括小數點) **--
--**dout(4)代表小數點,低電平點亮 **--
code1: process (dout,reg_datain)
begin
case dout(3 downto 0) is
when "0000"=>dout_led<=dout(4)&"0000001";
when "0001"=>dout_led<=dout(4)&"1001111";
when "0010"=>dout_led<=dout(4)&"0010010";
when "0011"=>dout_led<=dout(4)&"0000110";
when "0100"=>dout_led<=dout(4)&"1001100";
when "0101"=>dout_led<=dout(4)&"0100100";
when "0110"=>dout_led<=dout(4)&"0100000";
when "0111"=>dout_led<=dout(4)&"0001111";
when "1000"=>dout_led<=dout(4)&"0000000";
when "1001"=>dout_led<=dout(4)&"0000100";
--"DOUT_LED"送給數碼管;
when others=>dout_led<=reg_datain(7)®_datain(0)®_datain(1)®_datain(2)®_datain(3)®_datain(4)®_datain(5)®_datain(6);
--"DOUT_LED"送給發光二極管;
end case;
end process;
end Behavioral;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -