ACD0809 管脚及功能:
(1) IN7~IN0——模拟量输入通道;
(2) A、B、C——地址线,用于对模拟通道进行选择;
(3) ALE——地址锁存允许信号,对应 ALE 的上跳沿,A、B、
C 地址送入地址锁存器;
(4) START——启动信号,START 的上跳沿,所有内部寄存
器清零;START 的下跳沿时,开始进行 A/D 转换;在
A/D 转换期间,START 应保持低电平;
(5) D7~D0——数据输出线;
(6) OE——输出允许信号,低电平时,输出数据呈高阻态;
高电平时,向单片机输出转换得到的数据;
(7) CLK——时钟信号;
(8) EOC——转换结束信号,A/D 转换结束时,发出一个正
脉冲;
(9) Vref——参考电压;
(10)Vcc——电源电压+5V;
(11)GND——接地端。
设计思路及源代码
根据设计任务与工作原理,可以将数字电压表分为以下几个模块实现:
1. A/D 采样控制器;
2. 电压数据转换器;
3. LED 七段码显示器(通过实验平台实现)。
系统设计框图如下图所示
Din[7..0]
clk
eoc
rst
Add[2..0]
ale
oe
Start
/
A
D
采
样
控
制
器
电 压 数 据
转换器
L
E
D
七
段
码
显
示
器
A[7..0]
B[7..0]
C[7..0]
数字电压表系统框图
各文件功能说明及其源代码:
1.顶层文件 dvd 实现数字电压表的整体功能,其中包括 ADC0809 控制器和电压数据转换器两
个功能模块。
2.底层文件 AD_Ctrl 实现对 ADC0809 的时序控制,这里用变量 t 实现,也可用状态机实现,
而且可能会更简练一些。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
if eoc = '1' and t = 10 then
t := 0;
end if;
if t < 2 then
entity AD_Ctrl is
port(Din : in std_logic_vector(7 downto 0);
clk,eoc,rst : in std_logic;
add : out std_logic_vector(2 downto 0);
Dout :out std_logic_vector(7 downto 0);
ale,oe,start : out std_logic);
end AD_Ctrl;
architecture a of AD_Ctrl is
signal tt : std_logic_vector(2 downto 0);
begin
add <= "001";
process(clk,rst)
variable t : integer range 0 to 10;
begin
if rst = '1' then
t := 2;
tt <= "100";
t := t+1;
elsif t < 3 then
tt <= "010";
Dout <= Din;
t := t+1;
elsif t < 8 then
tt <= "001";
t := t+1;
elsif t < 10 then
tt <= "000";
t := t+1;
end if;
oe <= tt(2);
ale <= tt(1);
start <= tt(0);
end if;
end process;
elsif clk'event and clk = '1' then
end a;
3.底层文件 convert,由 part2.vhd 和 add_bcd3.vhd 两个模块组合而成,实现电压数据转
器的功能。
4. 底层文件 part2,实现将 8 位数字电压信号拆分为两部分。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity part2 is
port(clk
Din
highBCD,lowBCD : out std_logic_vector(11 downto 0));
: in std_logic;
: in std_logic_vector(7 downto 0);
end part2;
architecture aaa of part2 is
signal high,low : std_logic_vector(3 downto 0);
signal hb,lb
begin
: std_logic_vector(11 downto 0);
high <= Din(7 downto 4);
low <= Din(3 downto 0);
process(high,low)
begin
case high is
when "0000"=> hb <= "000000000000";--x"000";
when "0001"=> hb <= "000000110001";--x"031";
when "0010"=> hb <= "000001100011";--x"063";
when "0011"=> hb <= "000010010100";--x"094";
when "0100"=> hb <= "000100100101";--x"125";
when "0101"=> hb <= "000101010111";--x"157";
when "0110"=> hb <= "000110001000";--x"188";
when "0111"=> hb <= "001000100000";--x"220";
when "1000"=> hb <= "001001010001";--x"251";
when "1001"=> hb <= "001010000010";--x"282";
when "1010"=> hb <= "001100010100";--x"314";
when "1011"=> hb <= "001101000101";--x"345";
when "1100"=> hb <= "001101110110";--x"376";
when "1101"=> hb <= "010000001000";--x"408";
when "1110"=> hb <= "010000111001";--x"439";
when "1111"=> hb <= "010001110001";--x"471";
when others => NULL;
end case;
case low is
when "0000"=> lb <= "000000000000";--x"000";
when "0001"=> lb <= "000000000010";--x"002";
when "0010"=> lb <= "000000000100";--x"004";
when "0011"=> lb <= "000000000110";--x"006";
when "0100"=> lb <= "000000001000";--x"008";
when "0101"=> lb <= "000000010000";--x"010";
when "0110"=> lb <= "000000010010";--x"012";
when "0111"=> lb <= "000000010100";--x"014";
when "1000"=> lb <= "000000010110";--x"016";
when "1001"=> lb <= "000000011000";--x"018";
when "1010"=> lb <= "000000100000";--x"020";
when "1011"=> lb <= "000000100010";--x"022";
when "1100"=> lb <= "000000100100";--x"024";
when "1101"=> lb <= "000000100101";--x"025";
when "1110"=> lb <= "000000100111";--x"027";
when "1111"=> lb <= "000000101001";--x"029";
when others => NULL;
end case;
end process;
process(clk)
begin
if clk'event and clk = '1' then
highBCD <= hb;
lowBCD <= lb;
end if;
end process;
end aaa;
5.底层文件 add_bcd.vhd,实现两个 1 位 BCD 码的加法。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity add_bcd is
port(Cin
a,b
Cout
s
: in std_logic;
: in std_logic_vector(3 downto 0);
: out std_logic;
: out std_logic_vector(3 downto 0));
end add_bcd;
architecture aaa of add_bcd is
begin
process
variable t : std_logic_vector(4 downto 0);
begin
if Cin = '1' then
t := a + b + 1;
else
t := a + b;
end if;
if t > 9 then
t := t - 10;
t(4) := '1';
else
t(4) := '0';
end if;
s <= t(3 downto 0);
Cout <= t(4);
end process;
end aaa;
6.底层文件 add_bcd3.vhd,实现两个 3 位 BCD 码的加法运算。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity add_bcd3 is
port(clk,Cin: in std_logic;
a,b
Cout
s
: in std_logic_vector(11 downto 0);
: out std_logic;
: out std_logic_vector(11 downto 0));
end add_bcd3;
architecture aaa of add_bcd3 is
component add_bcd
port(Cin
a,b
Cout
s
: in std_logic;
: in std_logic_vector(3 downto 0);
: out std_logic;
: out std_logic_vector(3 downto 0));
end component;
signal t
signal outdata
signal outCout
begin
: std_logic_vector(1 downto 0);
: std_logic_vector(11 downto 0);
: std_logic;
l:add_bcd port map(Cin,a(3 downto 0),b(3 downto 0),t(0),outdata(3 downto 0));
m:add_bcd port map(t(0),a(7 downto 4),b(7 downto 4),t(1),outdata(7 downto 4));
h:add_bcd port map(t(1),a(11 downto 8),b(11 downto 8),outCout,outdata(11
downto 8));
process(clk)
begin
if clk'event and clk = '1' then
s <= outdata;
Cout <= outCout;
end if;
end process;
end aaa;
DAC0832 的测试
library ieee;
use ieee.std_logic_1164.all;
entity te is
port(clk: in std_logic;
dout:out std_logic_vector(7 downto 0);
wr:out std_logic);
end te;
architecture a of te is
begin
--process(clk)
--begin
--if clk'event and clk='1' then
dout<="00000000";
wr<='0';
--end if;
--end process;
end a;
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity AD_Ctrl is
port(Din : in std_logic_vector(7 downto 0);
clk,eoc,rst : in std_logic;
add : out std_logic_vector(2 downto 0);
Dout :out std_logic_vector(7 downto 0);
ale,oe,start : out std_logic;
full,empty:in std_logic;
wr,rd:out std_logic);
end AD_Ctrl;
architecture a of AD_Ctrl is
signal tt : std_logic_vector(2 downto 0);
begin
add <= "001";
process(clk,rst)
variable t : integer range 0 to 10;
begin
if rst = '1' then
t := 2;
elsif clk'event and clk = '1' then
if eoc = '1' and t = 10 then
t := 0;
end if;
if t < 2 then
tt <= "100";
t := t+1;
elsif t < 3 then
tt <= "010";
Dout <= Din;
t := t+1;
elsif t < 8 then
tt <= "001";
t := t+1;
elsif t < 10 then
tt <= "000";
t := t+1;
end if;
oe <= tt(2);
ale <= tt(1);
start <= tt(0);
end if;
end process;
process(full,empty)
--signal wr_1,rd_1 : std_logic;
begin
if full='1' and empty='0' then
wr<='0';
rd<=clk;
elsif full='0' and empty='1' then
wr<=clk;
rd<='0';
end if;
end process;
--wr<=wr_1;
--rd<=rd_1;
end a;