📄 demo_adc.vhd
字号:
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 22:18:42 03/23/05
-- Design Name:
-- Module Name: digital_voltmeter - ADC
-- Project Name:
-- Target Device:
-- Tool versions:
-- Description:
-- 数字电压表
-- Dependencies:
-- 通过AD转换芯片(tlc549)将模拟电压转换成数字量在数码管上显示,显示的值即为电压值;
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity digital_voltmeter is
Port (clk1k : in std_logic; --50m系统时钟
din : in std_logic;
clk_tlc549 : out std_logic;
cs_tlc549 : out std_logic;
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);
dout_lcd : out std_logic_vector(19 downto 0));
end digital_voltmeter;
architecture ADC of digital_voltmeter 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;
begin
--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(clk1k)
variable reg : integer range 0 to 80000;
variable d1,d2,d3,d4,d5 : std_logic_vector(3 downto 0);
begin
if clk1k'event and clk1k='1' then
case current_state1 is
when st0=>
reg:=reg_din;
d1:="0000";d2:="0000";d3:="0000";d4:="0000";
d5:="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;
elsif reg>0 then reg:=reg-1;d5:=d5+1;
else current_state1<=st2;
end if;
when st2=>
reg_dout<=d1&d2&d3&d4;
dout_lcd<=d1&d2&d3&d4&d5;
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段译码(包括小数点)
code1: process (dout)
begin
case dout(3 downto 0) is
when "0000"=>dout_led<=dout(4)&"0000001";--dout(4)代表小数点,低电平点亮
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";
when others=>dout_led<=reg_datain(7)®_datain(0)®_datain(1)®_datain(2)®_datain(3)®_datain(4)®_datain(5)®_datain(6);
end case;
end process;
end ADC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -