第13章数字电压表设计实验(《EDA原理及应用》课件)

Download Report

Transcript 第13章数字电压表设计实验(《EDA原理及应用》课件)

EDA原理及应用
何宾
2008.11
第
13章
第十三章
数字电压表设计-本章概要
本章给出了PLD器件在数字和模拟系统的典型应用-数
字电压表的设计。数字电压表实际上是一个模拟和数字混
合系统,该设计通过A/D转换器将模拟信号转换成离散的
数字量,通过可编程逻辑器件PLD进行处理,最后通过7
段数码管显示测量值。
该章首先介绍了数字电压表的功能要求和整体结构;
随后具体介绍了数字电压表的模块设计,其中包括数字电
压表的控制信号、ADC转换原理和控制模块的具体结构。
本章最后详细描述了设计的具体实现过程,具体包括ADC
控制模块的原理及实现、显示控制模块原理及实现、顶层
模块的设计。
第十三章
● 数字电压表设计-数字电压表的功能要求
数字电压表是一个模拟和数字混合系统,该数字电压表完成
模拟直流信号的测试,并将结果在数码管上显示。数字电压表主
要有以下几个功能:
1、模拟信号通过ADC0809转换为离散的数字量,设计模块
和ADC0809通过并口连接,并且向ADC0809发出控制信号;
2、数字电压表设计模块,将外部的时钟信号分频后得到合
适的采样时钟送给ADC0809;
3、每当ADC0809完成一次模/数转换过程后,设计模块对采
样数据进行处理,并通过3个7段数码管显示测量的直流电压值。
●
第十三章
数字电压表设计-数字电压表的整体结构
第十三章
● 数字电压表设计-数字电压表的整体结构
从图中可以看出,实验平台上,在PLD和ADC0809之间加
入了ADC控制模块,由于该模块的加入使PLD产生ADC控制模
块可以识别的信号,然后送到ADC0809。图中的PLD的设计部
分和ADC控制模块、7段数码管、外部时钟信号、按键进行连接。
●
数字电压表设计-数字电压表控制信号
第十三章
该数字电压表的控制逻辑由PLD完成,该模块的输入和输出
接口由下面信号组成:
1、输入信号
外部时钟信号(clk_in)
外部复位信号(reset)
ADC转换后的数字信号(din)
ADC转换完的中断信号(INTR)
●
数字电压表设计-数字电压表控制信号
2、输出信号
ADC片选信号(ncs)
ADC读信号(nrd)
ADC写信号(nwr)
ADC通道选择信号(nadd)
ADC时钟信号(nclock)
LED选择信号(led_select)
LED数码显示控制信号(seg)
第十三章
● 数字电压表设计-ADC转换原理
第十三章
ADC0809是CMOS的8位A/D转换器,片内有8路模拟开关,
可控制8个模拟量中的一个进入转换器中。ADC0809的分辨率为8
位,转换时间约100us,含锁存控制的8路多路开关,输出有三态
缓冲器控制,单5V电源供电。
● 数字电压表设计-ADC转换原理
第十三章
● 数字电压表设计-控制模块结构
第十三章
● 数字电压表设计-控制模块结构
第十三章
1、ADC控制模块
ADC控制模块产生ADC控制模块需要的控制信号,同时读取
ADC转换后的中断信号和数据信号。
该设计采用了教学实验系统,该系统的ADC控制模块接收
ncs,nrd,nwr和nintr信号。图13.4给出了该模块的控制信号时序关
系。
● 数字电压表设计-控制模块结构
第十三章
2、显示控制模块
显示控制模块产生LED显示所需要的LED选择信号和LED数码
控制信号。
3、采样时钟生成模块
采样时钟生成模块对外部输入的1MHz信号进行分频后,为
ADC0809产生合适的采样时钟信号。
4、扫描时钟生成模块
扫描时钟生成模块对外部输入的1MHz信号进行分频后,为
LED正确显示测量值产生合适的扫描时钟信号。
●
数字电压表设计-主要控制信号说明
1、START是转换启动信号,
高电平有效;
2、ALE是3位通道选择地址
(ADDC、ADDB、
ADDA)信号的锁存信号。
当模拟量送至某一输入端
(如IN1或IN2等),由3位
地址信号选择,而地址信号
由ALE锁存;
第十三章
●
数字电压表设计-主要控制信号说明
第十三章
3、EOC是转换情况状态信号,当启动转换约100us后,EOC
产生一个负脉冲,以示转换结束;在EOC的上升沿后,若使输出
使能信号OE为高电平,则控制打开三态缓冲器,把转换好的8位
数据结果输出至数据总线。至此ADC0809的一次转换结束了。
● 数字电压表设计-控制时序说明
第十三章
●
数字电压表设计-实验箱控制信号
第十三章
在实验仪器中CS与WR相与后接在了ALE和START端,
CS与RD相与后接在了OE端,通过对时序和电路的综合考虑,
建议使用如下的AD控制时序。
● 数字电压表设计-FSM的设计
第十三章
可以将整个控制分成4个步骤状态:S0、S1、S2、S3,各状态
的动作方式如下:
1、状态S0:CS=1、WR=1、RD=0(由控制器发出信号要求
ADC0809开始进行模/数信号的转换)。
2、状态S1:CS=0、WR=0、RD=0 (ADC0809进行转换动作,
转换完毕后INT将低电位升至高电位)。
3、状态S2: CS=1、WR=0、RD=1(由控制器发出信号以读
取ADC0809的转换数据)。
4、状态S3: CS=0、WR=0、RD=0(由控制器读取数据总线
上的数字转换数据)。
●
数字电压表设计-FSM的状态图描述
S1
S4
S2
S3
第十三章
● 数字电压表设计-FSM的设计
第十三章
由上述的四个状态可以归纳出整个控制器的动作功能有:
1、负责在每个步骤送出所需的CS、WR、RD控制信号。
2、在状态S1时,监控INT信号是否由低变高,如此以便了解转换动
作结束与否。
3、在状态S3,读取转换的数字量。
●
数字电压表设计-编码转换电路
第十三章
计算转换后的数字电压信号与BCD码的对应关系:
对8位的ADC0809而言,它的输出准位共有2**8=256种,即它
的分辨率是1/256。
VIN= 输入到 ADC0808的电压
Vfs= 满量程电压
VZ= 0电压
DX= 输出的数字量
DMAX= 最大数字量
DMIN= 最小数字量
● 数字电压表设计-编码转换电路
第十三章
假设输入信号为0~5V电压范围,参考电压(Vref/2)为2.56V
时,则它最小输出电压是5V/256=0.01953V,这代表ADC0809所
能转换的最小电压值,我们在该实验中取最小电压准位为0.02V。
当ADC0809收到的信号是01110110(76H),则其对应的电压值
为:
76H×0.02V = 2.36V
● 数字电压表设计-编码转换电路
第十三章
要实现电压值与BCD码的对应关系用多种方法(如查表法、
比较法等)。查表法需要写大量的数据,比较麻烦,在示例程序
中使用了比较法。
● 数字电压表设计-具体算法
 例如:10100101表示165*2=330=101001010
 165/255*5=3.26,用三个七段数码管显示,分离3 2 6




=0011 ,0010,0110
将1010高四位,0101低四位分离.
0101表示0000,0000,1010, BCD码1
1010表示0010,1100,0000, BCD码2
下面就是BCD码1+BCD码2
第十三章
●






数字电压表设计-具体算法
第十三章
0000,0000,1010
+ 0010,1100,0000,
0010,1100,1010
0000,0011,0000
比如:9+1=10, 6+7=13,
BCD码的加法实际上就是10进制的加法
判断: 由于BCD码显示0-9,所以加法运算要符合BCD码的运算
当>9时,BCD+6,并且+1进位
否则<9,BCD<=BCD+1
● 数字电压表设计-VHDL描述














library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library work;
use work.disp_driver.all;
entity disp_controller is
port( rst : in std_logic;
scan_clk : in std_logic;
din : in std_logic_vector(7 downto 0);
sel : out std_logic_vector(1 downto 0);
seg : out std_logic_vector(6 downto 0);
dp : out std_logic);
end disp_controller;
第十三章
● 数字电压表设计-VHDL描述
architecture Behavioral of disp_controller is
signal vol_value : std_logic_vector(7 downto 0);
signal bcd_value : std_logic_vector(11 downto 0);
signal bcd_h,bcd_l : std_logic_vector(11 downto 0);
signal scan_out : std_logic_vector(1 downto 0);
begin
第十三章
●
数字电压表设计-VHDL描述
process(rst,scan_clk)
begin
if(rst='0')then
vol_value<="00000000";
bcd_value<="000000000000";
elsif(rising_edge(scan_clk))then
vol_value<=din;
bcd_h<=bin_bcd(vol_value(7 downto 4),'1');
bcd_l<=bin_bcd(vol_value(3 downto 0),'0');
bcd_value<=bcd_h+bcd_l;
if(bcd_value(3 downto 0)>"1001")then
bcd_value<=bcd_value+"000000000110";
end if;
if(bcd_value(7 downto 4)>"1001")then
bcd_value<=bcd_value+"000001100000";
end if;
end if;
end process;
第十三章
● 数字电压表设计-VHDL描述
process(scan_clk)
begin
if(rising_edge(scan_clk))then
if(scan_out="10")then
scan_out<="00";
else
scan_out<=scan_out+'1';
end if;
end if;
end process;
第十三章
● 数字电压表设计-VHDL描述
第十三章
process(scan_out)
begin
case scan_out is
when "00" =>
seg<=display(bcd_value(3 downto 0));sel<="00";dp<='0';
 when "01" =>

seg<=display(bcd_value(7 downto 4)); sel<="01";dp<='0';
 when "10" =>

seg<=display(bcd_value(11 downto 8));sel<="10";dp<='1';
 when others =>

seg<=display("1111");sel<="11";dp<='1';
 end case;
 end process;
 end Behavioral;
● 数字电压表设计-程序包的设计
第十三章
在该设计中,在处理数码管显示部分会多次使用到BCD码到7
段码,为了提高对程序代码的复用和减少程序代码长度,在设计
中将BCD码到7段码的转换过程通过函数调用实现。下面给出在
程序包中的函数声明过程。
●
数字电压表设计-程序包的设计
第十三章
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package disp_driver is
function display(a : in std_logic_vector(3 downto 0) ) return std_logic_vector;
function bin_bcd(bin : in std_logic_vector(3 downto 0); flag : std_logic)
return std_logic_vector;
end disp_driver;
●
数字电压表设计-程序包的设计
第十三章
package body disp_driver is
function bin_bcd(bin : std_logic_vector;flag : std_logic) return std_logic_vector is
variable bcd_x : std_logic_vector(11 downto 0);
begin
if(flag='0')then
case bin is
when "0000" => bcd_x:="000000000000"; when "0001" => bcd_x:="000000000010";
when "0010" => bcd_x:="000000000100";when "0011"=> bcd_x:="000000000110";
when "0100"=> bcd_x:="000000001000";when "0101"=> bcd_x:="000000001010";
when "0110"=> bcd_x:="000000001100";when "0111"=> bcd_x:="000000001110";
when "1000"=> bcd_x:="000000010000";when "1001"=> bcd_x:="000000010010";
when "1010"=> bcd_x:="000000100000";when "1011"=> bcd_x:="000000100010";
when "1100"=> bcd_x:="000000100100";when "1101"=> bcd_x:="000000100110";
when "1110"=> bcd_x:="000000101000";when "1111"=> bcd_x:="000000110000";
when others => bcd_x:="111111111111";
end case;
elsif(flag='1')then
● 数字电压表设计-程序包的设计
第十三章
case bin is
when "0000" => bcd_x:="000000000000";when "0001" => bcd_x:="000000110010";
when "0010" => bcd_x:="000001100100";when "0011"=> bcd_x:="000010010110";
when "0100"=> bcd_x:="000100101000";when "0101"=> bcd_x:="000101100000";
when "0110"=> bcd_x:="000110010010";when "0111"=> bcd_x:="001000100100";
when "1000"=> bcd_x:="001001010110";when "1001"=> bcd_x:="001010001000";
when "1010"=> bcd_x:="001100110010";when "1011"=> bcd_x:="001101010010";
when "1100"=> bcd_x:="001110000100";when "1101"=> bcd_x:="010000010110";
when "1110"=> bcd_x:="010001001000";when "1111"=> bcd_x:="010010000000";
when others => bcd_x:="111111111111";
end case;
end if;
return bcd_x;
end bin_bcd;
● 数字电压表设计-程序包的设计



















function display (a : std_logic_vector ) return std_logic_vector is
variable r : std_logic_vector(6 downto 0);
begin
case a is
when "0000" => r:="0111111";
when "0001" => r:="0000110";
when "0010" => r:="1011011";
when "0011" => r:="1001111";
when "0100" => r:="1100110";
when "0101" => r:="1101101";
when "0110" => r:="1111101";
when "0111" => r:="0000111";
when "1000" => r:="1111111";
when "1001" => r:="1101111";
when others => r:="1111111";
end case;
return r;
end display;
end disp_driver;
第十三章
● 数字电压表设计-顶层模块
















library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity top is
port( rst : in std_logic;
clk : in std_logic;
int : in std_logic;
cs : out std_logic;
wr : out std_logic;
rd : out std_logic;
din : in std_logic_vector(7 downto 0);
sel : out std_logic_vector(1 downto 0);
seg : out std_logic_vector(6 downto 0);
dp : out std_logic);
end top;
第十三章
● 数字电压表设计-顶层模块














architecture Behavioral of top is
signal d : std_logic_vector(7 downto 0);
component adc0809_controller
port(
clk : in std_logic;
rst : in std_logic;
int : in std_logic;
cs : out std_logic;
wr : out std_logic;
rd : out std_logic;
din : in std_logic_vector(7 downto 0);
dout : out std_logic_vector(7 downto 0)
);
end component;
第十三章
● 数字电压表设计-顶层模块









component disp_controller
port(
rst : in std_logic;
scan_clk : in std_logic;
din : in std_logic_vector(7 downto 0);
sel : out std_logic_vector(1 downto 0);
seg : out std_logic_vector(6 downto 0);
dp : out std_logic);
end component;
第十三章
● 数字电压表设计-顶层模块











Inst_adc0809_controller1: adc0809_controller
port map(
clk =>clk,
rst =>rst,
int =>int,
cs =>cs,
wr =>wr,
rd =>rd,
din =>din,
dout =>d
);
第十三章
● 数字电压表设计-顶层模块










Inst_disp_controller1:disp_controller
port map(
rst=>rst,
scan_clk=>clk,
din=>d,
sel =>sel,
seg =>seg,
dp =>dp
);
end Behavioral;
第十三章
●
数字电压表设计-顶层约束
第十三章
该设计在基于xilinx的SPARTAN3的xc3s400pqg208-4c器件上实
现,在百科融创的EDA-IV实验平台上测试完成,在验证前,要进
行设计约束,在这里只对管脚进行约束。该约束文件的格式是
Xilinx的用户约束文件UCF的格式。采用不同的EDA平台时,需
要使用不同的用户约束文件格式。下面的约束仅供读者参考。
●
数字电压表设计-顶层约束
 #PACE: Start of Constraints generated















by PACE
#PACE: Start of PACE I/O Pin
Assignments
NET "clk" LOC = "p72" ;
NET "cs" LOC = "p68" ;
NET "din<0>" LOC = "p65" ;
NET "din<1>" LOC = "p63" ;
NET "din<2>" LOC = "p61" ;
NET "din<3>" LOC = "p57" ;
NET "din<4>" LOC = "p51" ;
NET "din<5>" LOC = "p48" ;
NET "din<6>" LOC = "p45" ;
NET "din<7>" LOC = "p43" ;
NET "dp" LOC = "p40" ;
NET "int" LOC = "p37" ;
NET "rd" LOC = "p35" ;
NET "rst" LOC = "p33" ;
•
•
•
•
•
•
•
•
•
•
•
第十三章
NET "seg<0>" LOC = "p27" ;
NET "seg<1>" LOC = "p24" ;
NET "seg<2>" LOC = "p21" ;
NET "seg<3>" LOC = "p19" ;
NET "seg<4>" LOC = "p16" ;
NET "seg<5>" LOC = "p13" ;
NET "seg<6>" LOC = "p11" ;
NET "sel<0>" LOC = "p9" ;
NET "sel<1>" LOC = "p5" ;
NET "wr" LOC = "p7" ;
#PACE: Start of PACE Area
Constraints
• #PACE: Start of PACE Prohibit
Constraints
• #PACE: End of Constraints
generated by PACE
第13章 习 题
1、说明基于PLD的数字电压表的结构及其实现原理。
2、在ISE软件和相关的硬件平台上完成本章所介绍的
数字电压表的设计。