ADC0809驱动FPGA实现的verilog程序

合集下载

201114xxx-xxx-ex4 用状态机实现ADC0809的采样控制电路

201114xxx-xxx-ex4  用状态机实现ADC0809的采样控制电路

实验(四)一、实验名称:用状态机实现ADC0809的采样控制电路二、实验目的:1.掌握ADC0809采样控制电路的工作原理。

2.进一步熟悉用quartusII建立程序、编译、仿真及下载的操作流程并学会ADC0809采样控制电路的Verilog硬件设计。

三、实验原理:ADC0809是CMOS的8位A/D转换器,片内有8路模拟开关,可控制8个模拟量中的一个进入转换器中。

ADC0809的分辨率为8位,转换时间约100us,含锁存控制的8路多路开关,输出由三态缓冲器控制,单5V电源供电。

主要控制信号如图1所示:START是转换启动信号,高电平有效;ALE是3位通道选择地址(ADDC、ADDB、ADDA)信号的锁存信号。

当模拟量送至某一输入端(如IN1或IN2等),由3位地址信号选择,而地址信号由ALE锁存;EOC是转换情况状态信号,当启动转换约100us后,EOC产生一个负脉冲,以示转换结束;在EOC的上升沿后,若使输出使能信号OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。

至此ADC0809的一次转换结束。

图1 控制信号波形四、实验内容1.在QuartusII软件下创建一工程工程名为ADC0809ctl,芯片名为EP1K30TC1—3实验代码如下:module ADC0809ctl(clk,eoc,din,start,oe,clock,q);input clk,eoc;input [7:0]din;output start,oe,clock;output [7:0]q;reg start,oe,lock;reg[4:0]cs,ns;reg [7:0]q;parameter s0=0,s1=1,s2=2,s3=3,s4=4;always @(posedge clk)begin cs<=ns;endalways @(cs,eoc)begincase(cs)s0:begin ns<=s1;start<=0;oe<=0;lock<=0;ends1:begin ns<=s2;start<=1;oe<=0;lock<=0;ends2:beginbegin if(eoc==1)ns<=s3;else ns<=s2;endstart<=0;oe<=0;lock<=0;ends3:begin ns<=s4;start<=0;oe<=1;lock<=0;ends4:begin ns<=s0;start<=0;oe<=1;lock<=1;enddefault:begin ns<=s0;start<=0;oe<=0;lock<=0;endendcaseendalways @(posedge lock)begin q<=din;endassign clock=clk;endmodule2、全程编译前约束项目设置选择FPGA目标芯片——选择配置器件的工作方式——选择配置器件和编程方式——选择目标器件引脚端口状态——选择Verilog语言版本3、全程综合与编译Processing——Start Compilation启动全程编译五、实验电路以及仿真1.ADC0809ctl的RTL图2.状态转换图3.时序仿真4.功能仿真建立功能仿真的网表,进行功能仿真5.将实验箱和PC合理连接起来。

EDA用状态机实现ADC0809的采样电路设计

EDA用状态机实现ADC0809的采样电路设计

实验六用状态机实现ADC0809的采样电路设计(1)【实验目的】1.设计实现ADC0809采样的状态机电路;2.掌握状态机的Verilog设计方法;3.学习设计仿真工具的使用方法;4.学习层次化设计方法;【实验内容】1.设计实现ADC0809采样电路,启动信号START高电平开始AD转换,此时转换结束标志变为0,当EOC 由低变为高,表示转会结束,此时可以置OE为1,ADC输出转换结果。

ADC0809控制时序如下:2.编制仿真测试文件,对实验六设计的ADC0809采样电路进行功能仿真。

3.下载并验证ADC0809的功能。

【实验原理】ADC0809是CMOS的8位A/D转换器,片内有8路模拟开关,可控制8个模拟量中的一个进入转换器中。

ADC0809的分辨率为8位,转换时间约100us,含锁存控制的8路多路开关,输出有三态缓冲器控制,单5V电源供电。

主要控制信号说明:如图1所示,START是转换启动信号,高电平有效;ALE是3位通道选择地址(ADDC、ADDB、ADDA)信号的锁存信号。

当模拟量送至某一输入端(如IN1或IN2等),由3位地址信号选择,而地址信号由ALE锁存;EOC是转换情况状态信号(类似于AD574的STA TUS),当启动转换约100us后,EOC产生一个负脉冲,以示转换结束;在EOC的上升沿后,若使输出使能信号OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。

至此ADC0809的一次转换结束了。

【程序源代码】module ADC0809C (clk,D,EOC,start,LOCK,OE,Q);input clk,EOC;input [7:0] D;output start,LOCK,OE;output [7:0] Q;reg start,LOCK,OE;reg [7:0] Q;parameter s0=0,s1=1,s2=2,s3=3,s4=4;reg[4:0] c_s,n_s;assign clock=clk;always @(posedge clk)c_s<=n_s;always @(c_s,EOC)begincase(c_s)s0: beginstart<=0;OE<=0;LOCK<=0;n_s<=s1;ends1: beginstart<=1;OE<=0;LOCK<=0; n_s<=s2;ends2: beginstart<=0;OE<=0;LOCK<=0; if(EOC) n_s<=s3;else n_s<=s2;ends3: beginstart<=0;OE<=1;LOCK<=0; n_s<=s4;ends4: beginstart<=0;OE<=1;LOCK<=1; n_s<=s0;enddefaultbeginstart<=0;OE<=0;LOCK<=0; n_s<=s0;endendcaseendalways@(posedge clk)beginQ<=D;endendmodule【元件符号与总框图】【仿真和测试结果】上图为仿真结果,clk,D,EOC,为输入信号,当EOC输入为低电平时,A/D转换开始转换,如上图仿真结果显示,当EOC低电平结束时,OE为高电平,然后延时一段即LOCK信号为1时,A/D转换器转换的值送到Q输出。

FPGA与ADC0809接口电路详解

FPGA与ADC0809接口电路详解

FPGA与ADC0809接口电路详解注:(1)本程序基于FPGA和vhdl编写有详尽的程序解释和原理分析以及原理图,状态图(2)对于adc0809具体资料可上网查在此不累述一.FPGA与ADC0809的接口电路图原理二.关于ADC0809的说明(重点)(1)ale信号(引脚):高电平时把三个地址信号送入地址锁存器,并经译码器得到地址数据,以选择相应的模拟输入通道。

(2)oe信号(引脚)en使能信号:电平由低变高时,打开数据输出锁存器,将转换数据送到数据总线上(3)eoc信号(引脚):eoc为高电平时完成转换,为低电平时正在转换。

(4)start信号(引脚):要给start线送一个100ns宽的启动正脉冲,start下跳沿时,开始进行A/D转换,在转换期间start以保持低电平。

三.转换状态图对于状态图的真值表未列出 注意对应的注释为vhdl 语句ale<='1';start<='0';en<='0';----eoc='1' ale<='0';start<='0';en<='0';--再次检测数据是否转换完 if eoc='0' then next_state<=st4;else next_state<=st5;器,将数据送入数据总线存器四.ADC0809采样接口电路程序--*********ADC0809采样控制*************--******因为FPGA 的时钟频率为50MHz ,则256分频后,即ADC0809输入时钟为195KHz****** --******对ADC0809进行简单的采样控制,得到的数据进FPGA 送到8个并排的数码管显示***** library ieee;use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity PL_AD isport ( d : in std_logic_vector(7 downto 0); --ADC0809输出的采样数据输入FPGA clk,eoc: in std_logic; --clk 为系统时钟,eoc 为ADC0809转换结束信号输入FPGA lock1,start, ale,en: out std_logic; --ADC0809控制信号FPGA 输出信号 abc_in :in std_logic_vector(2 downto 0); --模拟选通信号abc_out :std_logic_vector(2 downto 0);--ADC0809模拟信号选通信号q : out std_logic_vector(7 downto 0));送至8个并排数码管信号FPGA 输出数字信号 end pl_AD;architecture behav of PL_AD istype states is ( st0,st1, st2, st3, st4,st5,st6);--定义状态类型枚举类型signal current_state, next_state:states:=st0;--定义总体两个状态现态和次态并且初值为st0态signal regl :std_logic_vector(7 downto 0);--定义中间寄存器signal lock : std_logic;signal qq:std_logic_vector(7 downto 0);--定义计数器用于分频begincom:process(current_state,eoc) –此进程主要是驱动ADC0809工作即数据转换过程begincase current_state iswhen st0=>next_state<=st1;ale<='0';start<='0';en<='0';--准备when st1=>next_state<=st2;ale<='1';start<='0';en<='0';--三个地址信号送入地址锁存器when st2=>next_state<=st3;ale<='0';start<='1';en<='0';--开始数据转换when st3=> ale<='0';start<='0';en<='0';--检测数据是否转换完if eoc='1' then next_state<=st3;else next_state<=st4;end if;when st4=> ale<='0';start<='0';en<='0';--再次检测数据是否转换完if eoc='0' then next_state<=st4;else next_state<=st5;end if;when st5=>next_state<=st6;ale<='0';start<='0';en<='1'; --打开输出数据锁存器,将数据送入数据总线when st6=>next_state<=st0;ale<='0';start<='0';en<='1';regl<=d;--打开输出数据锁存器,将数据送入寄存器regl when others=> next_state<=st0;ale<='0';start<='0';en<='0';end case;end process;clock:process(clk) --对系统时钟进行分频,得到驱动ADC0809的时钟信号beginif clk'event and clk='1' then qq<=qq+1;if QQ="01111111" THEN lock<='1';--实现分频current_state <=next_state;--在lock上升沿,转换至下一状态elsif qq<="01111111" then lock<='0';end if;end if;end process;q<=regl;--寄存器数据输出即FPGA输出lock1<=lock;abc_out<=abc_in;--模拟选通信号送往ADC0809end behav;注:有错when st3=> ale<='0';start<='0';en<='0';--检测数据是否转换完if eoc='1' then next_state<=st3;else next_state<=st4;end if;when st4=> ale<='0';start<='0';en<='0';--再次检测数据是否转换完if eoc='0' then next_state<=st4;else next_state<=st5;end if;不过我这里的注释好像错了,这两个when合起来才是检测数据是否转换完的。

EDA 用状态机实现ADC0809采样电路设计

EDA  用状态机实现ADC0809采样电路设计

实验用状态机实现ADC0809采样电路设计【实验目的】(1)熟悉QuartusⅡ7.0的使用方法。

(2)学习ADC0809采样电路设计的verilog程序编写,编译,仿真,管脚验证及下载。

【实验要求】用ADC0809采样电压实现采样。

【实验内容及步骤】1)QuartusⅡ7.0的破解1.用Quartus_II_7.0_dll破解器.exe破解C:\altera\70\quartus\bin下的sys_cpt.dll文件(运行Quartus_II_7.0_dll破解器.exe后,首先要点击“浏览”选中sys_cpt.dll,安装默认的sys_cpt.dll路径是在C:\altera\70\quartus\bin下,选中sys_cpt.dll后再点击“应用”。

2.把文件夹“包括Quartus 7.0和DSP_builde7.0的注册号”中的licenseV70.dat文件,拷到altera的按装目录中,然后在Quartus 7.0中点击"tools"->"license setups..."指定license 所在的目录。

至此就完成Quartus 7.0的破解了。

(2)输入源代码module adc0809 (D,CLK,EOC,RST,ALE,START,OE,ADDA,Q,LOCK_T); input [7:0] D;input CLK,RST;output EOC;output ALE;output START,OE;output ADDA,LOCK_T;output [7:0] Q;reg ALE,START,OE,EOC;parameter s0=0,s1=1,s2=2,s3=3,s4=4;reg [4:0] cs,next_state;reg [7:0] REGL;reg LOCK;reg [3:0] acc;always @(cs or EOC) begincase (cs)s0:begin ALE=0;START=0;OE=0;LOCK=0;next_state=s1;ends1:begin ALE=1;START=1;OE=0;LOCK=0;next_state=s2;ends2:begin ALE=0;START=0;OE=0;LOCK=0;if(EOC==1'B1) next_state=s3;else next_state=s2;ends3:begin ALE=0;START=0;OE=1;LOCK=0;next_state=s4;ends4:begin ALE=0;START=0;OE=1;LOCK=1;next_state=s0;endendcase endalways @(posedge CLK or posedge RST) begin if(RST) cs=s0;else cs=next_state; endalways @ (posedge LOCK)if(LOCK) REGL=D;always @(posedge CLK or posedge START) beginif(START) beginEOC=0;acc=0;endelse begin if(!EOC) beginif(acc==4) EOC=1;else acc=acc+1;endendendassign ADDA=0;assign Q=REGL;assign LOCK_T=LOCK;endmodule3)保存编译设置DeviceTools工具栏→netlist viewer s→RTL viewers波形仿真【实验心得与体会】通过这次实验我熟悉了QuartusⅡ7.0的破解方法及使用;学会了Adc0809采样电路的verilog程序的编写,编译,仿真,下载,管脚的验证。

FPGA直接控制ADC0809对模拟信号进行采样.

FPGA直接控制ADC0809对模拟信号进行采样.

第二章总体方案设计2.1 系统方案设计在以往的A/D器件采样控制设计中,多数是以单片机或CPU为控制核心,虽然编程简单,控制灵活,但缺点是控制周期长,速度慢。

单片机的速度极大的限制了A/D高速性能的利用,而FPGA的时钟频率可高达100MHz以上。

本设计以高集成度的芯片为核心,进行时序控制、码制变换。

具有开发周期短,灵活性强,通用能力好,易于开发、扩展等优点。

既降低了设计难度,又加快了产品的开发周期。

基于FPGA的信号采集系统主要有:A/D转换器,FPGA,RS232通信,PC 机组成。

A/D 转换器对信号进行会采集,A/D 内部集成了采样、保持电路,可有效的降低误差,减少外围电路的设计,降低系统的功耗。

A/D在接受到指令后进行采集,FPGA采集控制模块首先将采集到的通过A/D 转换城的数字信号引入FPGA,而后对数字信号送往算法实现单元进行处理,并存于FPGA内部RAM 中,再将数据由RS232传送到PC上做FFT,实现对采集信号的时域和频域的显示。

图2.1.1系统的总体框图:FPGA的设计结构如图2.1.2所示。

数字倍频器的倍频输出提供ADC控制器的采样触发脉冲。

根据ADC0809操作时序,ADC控制器来实现ADC0809的数据采集操作,采样的时机由倍频器来控制。

控制器每控制完成一次采样操作,则停止等待下一个触发脉冲的到来。

倍频器每输出一个低电平脉冲,ADC采样控制器的状态机进行一次采样操作。

在倍频器的触发控制下,完成被测信号一个基波周期N个点的等间隔采样,同时数字倍频器跟踪输入信号的频率的变化,尽可能地保持N个点的采样宽度正好为被测信号一个周波的宽度。

-时钟分配及各模块的控制:在协调模块工作时,起到很重要的作用。

引进晶振产的时钟信号,根据实际需要对起进行倍频或分频,使A/D的采样频率,RAM的读写频率,信号处理实现的核心模块的工作频率一致。

图2.1.2系统具体流程框图2.2 各功能模块的设计方案2.2.1 FPGA最小系统板方案设计FPGA是英文Field Programmable Gate Array的缩写,即现场可编程门阵列,它是在PAL、GAL、EPLD等可编程器件的基础上进一步发展的产物[4]。

adc0809 fpga点正显示

adc0809 fpga点正显示

library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ad0809 ISPORT (clk,int : in std_logic; --时钟输入cs,wr,rd : out std_logic; ---AD控制信号tongdao :buffer std_logic_vector(1 DOWNTO 0); --通道选择信号selout : out std_logic_vector(1 DOWNTO 0); --位选输出datout : out std_logic_vector(15 DOWNTO 0) ); --段码输出END ad0809 ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------architecture arch of ad0809 istype state is (s0,s1,s2,s3);---状态定义signal current_state,next_state : state ;signal cnt :std_logic_vector(2 DOWNTO 0);signal sel :std_logic_vector(1 DOWNTO 0);signal tongdao1,tongdao2,tongdao3,tongdao4:std_logic_vector(7 DOWNTO 0);signal tmp :std_logic_vector(7 DOWNTO 0);signal flag :std_logic;beginprocess(current_state)begincase current_state iswhen s0 => cs<='1';wr<='1'; rd<='0';flag<= '0';next_state <= s1;when s1 => cs<='0';wr<='0'; rd<='0'; flag<= '0';if int ='1' thennext_state<= s2;elsenext_state<= s1;end if;when s2 => cs<='1';wr<='0';rd<='1';flag<= '1'; --当flag=1时开始采集数据next_state<= s3;when s3 => cs<='0';wr<='0';rd<='0';flag<= '0';next_state<= s0;end case;end process;process (clk)beginif (clk'event and clk='1') thencurrent_state<=next_state; ---状态转换end if;end process;process(flag)beginif flag'event and flag='1' thentongdao<= tongdao+1; --通道加1sel<= sel+1; --位选加一case tongdao iswhen "00" => tongdao1<=data; ---将对应通道值送出when "01" => tongdao2<=data;when "10" => tongdao3<=data;when "11" => tongdao4<=data;when others => null;end case;------------------每个通道所对应的位选case sel iswhen "00" => tmp<=tongdao1; --将对应值送给tmp,进行输出处理when "01" => tmp<=tongdao2;when "10" => tmp<=tongdao3;when "11" => tmp<=tongdao4;when others => null;end case;selout<=sel;end if;end process;process(sel)begincase tmp is ---将转换得来的值处理,并选择相应输出数据when "00000000" => datout<="0000000000000001" ;when "00010000" => datout<="0000000000000011" ;when "00100000" => datout<="0000000000000111" ;when "00110000" => datout<="0000000000001111" ;when "01000000" => datout<="0000000000011111" ;when "01010000" => datout<="0000000000111111" ;when "01100000" => datout<="0000000001111111" ;when "01110000" => datout<="0000000011111111" ;when "10000000" => datout<="0000000111111111" ;when "10010000" => datout<="0000001111111111" ;when "10100000" => datout<="0000011111111111" ;when "10110000" => datout<="0000111111111111" ;when "11000000" => datout<="0001111111111111" ;when "11010000" => datout<="0011111111111111" ;when "11100000" => datout<="0111111111111111" ;when "11110000" => datout<="1111111111111111" ;when others => null;end case;end process;end arch;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;---*******************************************************--clk--********************************************************entity adc isport( clk:in std_logic;wr,rd,cs:out std_logic; --外部时钟输入int:in std_logic; --数据转换完成dat:in std_logic_vector(7 downto 0); --AD数据输入sel:out std_logic_vector(3 downto 0); --点阵位选datout:out std_logic_vector(15 downto 0)); --点阵段选end entity;--*********************************************************--********************************************************* architecture behave of adc istype states is( s0,s1, s2, s3);signal datin:std_logic_vector(7 downto 0); --输入数据signal current_state,next_state:states:=s0; --现态和次态signal eoc:std_logic; --转换完成标志signal cnt:std_logic_vector(1 downto 0); -- 计数--********************状态转换**************************************** begineoc<=int;qdadc:process(current_state,eoc)begincase current_state iswhen s0=> next_state<=s1;cs<='1';wr<='1';rd<='0';when s1=> cs<='0';wr<='0';rd<='0';if eoc='1' thennext_state<=s2; --如果转换完成则条到下一个状态elsenext_state<=s1;--否则将继续上一个状态等待end if;when s2=>next_state<=s3;cs<='1';wr<='0';rd<='1';datin<=dat; --转换完成接受数据when s3=>next_state<=s0;cs<='0';wr<='0';rd<='0';when others=> next_state<=s0;cs<='1';wr<='1';rd<='0';end case;end process;fenpin:process(clk)beginif clk'event and clk='1' thenif cnt="11" thencurrent_state<=next_state; --将次态给现态的值else cnt<=cnt+1;end if;end if;end process;dataa<=datin;--***************************显示译码***********************************************disp: blockbeginwith datin(7 downto 4)select ---对高四位数值进行判断datout<="0000000000000001" when"0000","0000000000000011" when"0001","0000000000000111" when"0010","0000000000001111" when"0011","0000000000011111" when"0100","0000000000111111" when"0101","0000000001111111" when"0110","0000000011111111" when"0111","0000000111111111" when"1000","0000001111111111" when"1001","0000011111111111" when"1010","0000111111111111" when"1011","0001111111111111" when"1100","0011111111111111" when"1101","0111111111111111" when"1110","1111111111111111" when"1111","0000000000000000" when others;sel<="0001";end block;--************************************************end behave;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;---*******************************************************--clk系统时钟,sel位选datout:段码输出--********************************************************entity adc isport( clk:in std_logic;wr,rd,cs:out std_logic;int:in std_logic;dat:in std_logic_vector(7 downto 0);sel:out std_logic_vector(3 downto 0);datout:out std_logic_vector(15 downto 0));end entity;--*********************************************************--*********************************************************architecture behave of adc istype states is( s0,s1, s2, s3); --状态表signal datin:std_logic_vector(7 downto 0);--输入数据signal current_state,next_state:states:=s0;--现态,下一个状态signal eoc:std_logic;signal sel_dat:std_logic_vector(3 downto 0);--位选译码变量signal temp:std_logic_vector(4 downto 0);--译码中间值--************************************************************--**************************ad转换---------------------------begineoc<=int;qdadc:process(current_state,eoc)begincase current_state iswhen s0=> next_state<=s1;cs<='1';wr<='1';rd<='0';when s1=> cs<='0';wr<='0';rd<='0';if eoc='1' thennext_state<=s2; --如果转换成功,跳到下一个状态elsenext_state<=s1;--为转换成功,则继续等待end if;when s2=>next_state<=s3;cs<='1';wr<='0';rd<='1';datin<=dat;when s3=>next_state<=s0;cs<='0';wr<='0';rd<='0';when others=> next_state<=s0;cs<='1';wr<='1';rd<='0';end case;end process;---************************************************************************---*******************状态转换和译码************************************* zhuantai:process(clk)beginif clk'event and clk='1' thencurrent_state<=next_state;---状态变换sel_dat<=sel_dat-1; ----产生列扫描值sel<=sel_dat;if(datin(7 downto 4)>sel_dat) thentemp<="01111";elsif(datin(7 downto 4)=sel_dat)thentemp<='0'&datin(3 downto 0);elsetemp<="10000";end if;end if;end process;--*******************************************************************--temp由--*****************************显示部分****************************** disp: blockbeginwith temp selectdatout<="0000000000000001" when"00000","0000000000000011" when"00001","0000000000000111" when"00010","0000000000001111" when"00011","0000000000011111" when"00100","0000000000111111" when"00101","0000000001111111" when"00110","0000000011111111" when"00111","0000000111111111" when"01000","0000001111111111" when"01001","0000011111111111" when"01010","0000111111111111" when"01011","0001111111111111" when"01100","0011111111111111" when"01101","0111111111111111" when"01110","1111111111111111" when"01111","0000000000000000" when others;end block;--************************************************end behave;。

基于VerilogHDL的ADC0809采样控制器设计

基于VerilogHDL的ADC0809采样控制器设计

© 1994-2008 China Academic Journal Electronic Publishing House. All rights reserved.
<= 0 ;next state <= st3 ;end st3 :begin ale <= 0 ; start <= 0 ;oe <= 0 ;lock
2006 年第 12 期 信息技术
Information Technology
中图分类号 :TP331 文献标识码 :A 文章编号 :1009 - 2552 (2006) 12 - 0151 - 03
基于 Verilog HDL 的 ADC0809 采样控制器设计
基于 Verilog HDL 语言的 AΠD 采样控制器设计 源程序 :
module adc (d ,clk ,eoc ,lock ,ale ,start ,oe ,adda ,q , — 152 —
图 3 采样控制器模块图
reset) ; input reset ; input [ 7 :0 ] d ; input clk ,eoc ; output lock ,ale ,start ,oe ,adda ; output [ 7 :0 ] q ; reg [ 7 :0 ] q ; reg ale ,start ,oe ,adda ; reg [ 2 :0 ] current state ,next state ; reg lock ; ΠΠ定义状态 parameter st0 = 3’b000 ; parameter st1 = 3’b001 ; parameter st2 = 3’b010 ; parameter st3 = 3’b011 ; parameter st4 = 3’b100 ; parameter st5 = 3’b101 ; parameter st6 = 3’b110 ; ΠΠ组合逻辑 always @(current state or eoc) begin case (current state) st0 :begin ale <= 0 ; start <= 0 ;oe <= 0 ;lock

adc0809的的基本应用实例及程序

adc0809的的基本应用实例及程序

ADC0809与DAC0832进行ADDA转换程序使用0809将电压数据采集回来,然后再用DAC0832输出电压。

练习AD,DA的使用。

程序:#include<reg51.h>#include<absacc.h>#define DAC0832 XBYTE[0x7fff] /* 定义DAC0832端口地址*/#define uchar unsigned char#define uint unsigned intsbit ST=P3^0;sbit OE=P3^1;sbit EOC=P3^2;sbit CLK=P3^3;sbit A1=P3^4;sbit A2=P3^5;sbit A3=P3^7;void delay(unsigned int Delay) //Delay(1000)延时一秒{unsigned int q;for(;Delay>0;Delay--){ for(q=0;q<124;q++){;}}}/*void TimeInitial(){TMOD=0x20;TH1=0xff;TL1=0xff;EA=1;ET1=1;TR1=1;}*/uchar adin0(void) //AD0通道转换{uchar getdATa;//TimeInitial();ST=0;OE=0;ST=1;ST=0;A1=0;A2=0;A3=0;while(EOC==0);OE=1;getdA Ta=P1;OE=0;//TR1=0;return(getdATa);}uchar adin1(void) //AD1通道转换{uchar getdA Ta;//TimeInitial();ST=0;OE=0;ST=1;ST=0;A1=1;A2=0;A3=0;while(EOC==0);OE=1;getdA Ta=P0;OE=0;//TR1=0;return(getdATa);}void main(void){uchar dATa0,i;while(1){dA Ta0=adin0();DAC0832=dATa0;}}void time1(void) interrupt 3 using 0 {TH1=0xff;TL1=0xff;CLK=~CLK;}ADC0809 A/D转换程序基本知识ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。

8.4 ADC0809接口电路及程序设计

8.4 ADC0809接口电路及程序设计

分频模块(clock)



clock:process(clk) --对系统时钟进行分频,得到ADC0809转 换工作时钟 begin if clk'event and clk='1' then qq<=qq+1; --在clk1的上升沿, 转换至下一状态 if QQ="01111111" THEN clk1<='1'; current_state <=next_state; elsif qq<="01111111" then clk1<='0'; end if; end if; end process; q<=regl; abc_out<=abc_in; end behav;
ADC0809 VHDL采样控制程序设计
ADC0809的工作时序图





START是转换启动信号,一个正脉冲过后A/D开 始转换;ALE是3位通道选择地址(ADDC、 ADDB、ADDA)信号锁存信号。 当模拟量送至某一输入端(如IN-0或IN-1)等, 由3位地址信号选择,而地址信号由ALE锁存。 EOC是转换情况状态信号,当启动转换约100μs 后,EOC产生一个负脉冲,以示转换结束。 在EOC的上升沿后,且输出使能信号ENABLE为 高电平,则控制打开三态缓冲器,把转换好的8 位数据送至数据总线。 至此ADC0809的一次转换结束
FPGA与ADC0809接口电路原理图
ADC0809与FPGA接口电路设计


FPGA_IO1~8接收ADC0809 8位数数据; FPGA_IO9接收ADC0809 转换结束信号EOC; FPGA_IO10~12 为ADC0809提供8路模拟信号开 关的3位地址选通信号(ADD-A~C); FPGA_IO13 为ADC0809提供地址锁存控制信号 ALE:高电平时把三个地址信号送入地址锁存器, 并经译码器得到地址输出,以选择相应的模拟输 入通道;

实验六 用状态机实现ADC0809的采样控制电路

实验六 用状态机实现ADC0809的采样控制电路

实验六用状态机实现ADC0809的采样控制电路电子设计自动化实验报告实验六用状态机实现ADC0809的采样控制电路一、实验目的1. 熟悉Quartus?软件应用环境,了解实验流程。

2. 编写简单的Verilog代码,并在Quartus?中进行调试和验证,并在EDA6000中下载代码和验证。

3. 掌握状态机的Verilog设计方法,并用状态机实现ADC0809的采样控制电路。

二、实验原理本实验要实现用状态机实现ADC0809的采样控制电路。

ADC0809是CMOS的8位A/D转换器,片内有8路模拟,可控制8个模拟量中的一个进入转换器中。

ADC0809的分辨率为8位。

主要控制信号说明:START是转换开启信号,高电平有效;ALE为模拟信号输入选通端口地址锁存信号,上升沿有效;一旦START有效后,状态信号EOC即变为低电平,表示转换状态,转换时间约为100us,转换结束后,EOC变为高电平。

此后外部控制可以使OE由低电平变为高电平,则控制打开三态缓冲器,0809的输出数据总线D[7:0]从原来的高阻态变为输出数据有效。

三、实验内容1、用Verilog HDL语言实现编写实现ADC0809采样电路的程序。

、编程下载并在实验箱上进行验证 2四、实验步骤与结果1、新建Verilog工程项目,编写代码并保存至与模块名对应的项目文件夹。

2、编译程序,编译无误后,在【tools】里面选择RTL视图,观察电路结构。

在【tools】>【netlist viewers】里面选择State Machine Viewer,查看状态机转换图。

3、将实验箱和PC合理连接起来。

打开EDA6000软件,设置好芯片类型为ACEX1K(EP1K30TC144-3),载入模式14。

4、根据EDA6000界面内管脚对应芯片的实际管脚在QUARTUS?里面设定管脚号并检查无误。

5、将程序下载至FPGA试验箱内,并在EDA6000软件界面内进行验证测试。

VHDL实验:用状态机实现ADC0809的采样控制电路

VHDL实验:用状态机实现ADC0809的采样控制电路

VHDL实验二用状态机实现ADC0809的采样控制电路一、实验目的1.学习用状态机对A/D转换器ADC0809的采样控制电路的实现。

二、实验仪器1.PC机一台2.KHF-5 CPLD/FPGA实验开发系统一套。

三、实验要求1.查阅ADC0809芯片资料。

2.预习实验内容。

四、原理说明ADC0809是CMOS的8位A/D转换器,片内有8路模拟开关,可控制8个模拟量中的一个进入转换器中。

ADC0809的分辨率为8位,转换时间约100us,含锁存控制的8路多路开关,输出有三态缓冲器控制,单5V电源供电。

主要控制信号说明:如图1所示,START是转换启动信号,高电平有效;ALE是3位通道选择地址(ADDC、ADDB、ADDA)信号的锁存信号。

当模拟量送至某一输入端(如IN1或IN2等),由3位地址信号选择,而地址信号由ALE锁存;EOC是转换情况状态信号(类似于AD574的STATUS),当启动转换约100us后,EOC产生一个负脉冲,以示转换结束;在EOC的上升沿后,若使输出使能信号OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。

至此ADC0809的一次转换结束了。

图1五、实验内容及实验步骤1、利用quartus2进行文本编辑输入和仿真测试;给出仿真波形。

最后进行引脚锁定并进行测试,硬件验证对ADC0809的控制功能。

实验代码:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY adc0809 ISPORT ( ina : IN STD_LOGIC_VECTOR(7 DOWNTO 0); --0809的8位转换数据输出CLK ,EOC : IN STD_LOGIC; --CLK xitong工作时钟ALE, ck, OE : OUT STD_LOGIC; --ck是0809de 工作时钟adda,addb,addc:out std_logic;outa : OUT STD_LOGIC_VECTOR(13 DOWNTO 0) );END adc0809 ;ARCHITECTURE behav OF adc0809 IS--signal sa:std_logic_vector(7 downto 0);signal fp:std_logic_vector(9 downto 0);signal f:std_logic;TYPE states IS (st0, st2, st3,st4,st5,st6) ; --定义各状态子类型SIGNAL current_state, next_state: states :=st0 ;SIGNAL REGL : STD_LOGIC_VECTOR(7 DOWNTO 0);SIGNAL LOCK : STD_LOGIC; -- 转换后数据输出锁存时钟信号BEGINADDA <= '1';addb<='0';addc<='0';--sa<=ina;process( CLK)beginif( CLK'event and CLK='1')thenif fp=15 thenfp<="0000000000";f<=not f;elsefp<=fp+1;end if;end if;end process;ck<=f;PRO: PROCESS(current_state,EOC) BEGIN --规定各状态转换方式CASE current_state ISWHEN st0 => ALE<='0';START<='0';OE<='0';LOCK<='0' ;next_state <= st2;-- WHEN st1 => ALE<='1';START<='1';OE<='0';LOCK<='0' ;next_state <= st2;WHEN st2 => ALE<='1';START<='1';OE<='0';LOCK<='0' ;next_state <= st3;WHEN st3 => ALE<='0';START<='0';OE<='0';LOCK<='0';IF (EOC='1') THEN next_state <= st3; --测试EOC的下降沿ELSE next_state <= st4;END IF ;WHEN st4=> ALE<='0';START<='0';OE<='0';LOCK<='0';IF (EOC='0') THEN next_state <= st4; --测试EOC的上升沿,=1表明转换结束ELSE next_state <= st5; --继续等待END IF ;WHEN st5=> ALE<='0';START<='0';OE<='1';LOCK<='0';next_state <= st6;WHEN st6=> ALE<='0';START<='0';OE<='1';LOCK<='1';next_state <= st0;WHEN OTHERS => ALE<='0';START<='0';OE<='0';LOCK<='0';next_state <= st0;END CASE ;END PROCESS PRO ;PROCESS (f)BEGINIF ( f'EVENT AND f='1') THENcurrent_state <= next_state; -- 在时钟上升沿,转换至下一状态END IF;END PROCESS; -- 由信号current_state将当前状态值带出此进程,进入进程PROPROCESS (LOCK) -- 此进程中,在LOCK的上升沿,将转换好的数据锁入BEGINIF LOCK='1' AND LOCK'EVENT THEN REGL <= ina ;END IF;END PROCESS ;with REGL(3 downto 0) selectouta(6 downto 0) <="0110000"when"0001",--1"1101101"when"0010",--2"1111001"when"0011",--3"0110011"when"0100",--4"1011011"when"0101",--5"1011111"when"0110",--6"1110000"when"0111",--7"1111111"when"1000",--8"1111011"when"1001",--9"1110111"when"1010",--A"0011111"when"1011",--b"1001110"when"1100",--c"0111101"when"1101",--d"1001111"when"1110",--e"1000111"when"1111",--f"1111110"when others;--0with REGL(7 downto 4) selectouta(13 downto 7) <="0110000"when"0001",--1"1101101"when"0010",--2"1111001"when"0011",--3"0110011"when"0100",--4"1011011"when"0101",--5"1011111"when"0110",--6"1110000"when"0111",--7"1111111"when"1000",--8"1111011"when"1001",--9"1110111"when"1010",--A"0011111"when"1011",--b"1001110"when"1100",--c"0111101"when"1101",--d"1001111"when"1110",--e"1000111"when"1111",--f"1111110"when others;--0END behav;2、建议引脚锁定为:oe为p18。

ADC0809-VHDL程序并显示

ADC0809-VHDL程序并显示

--编程软件:ISE 10.1--10年北京市电设比赛准备程序,调了半天的程序,绝对能用,但是说不考了--后面有引脚配置代码--程序library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity adcok isPORT(D:IN STD_LOGIC_VECTOR(7 DOWNTO 0);CLK,EOC:IN STD_LOGIC;ALE,START,OE:OUT STD_LOGIC;ADDA:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);clockout:out std_logic;seg7 : out STD_LOGIC_VECTOR (6 downto 0);an : out STD_LOGIC_VECTOR (3 downto 0);dp : out STD_LOGIC);end adcok;architecture Behavioral of adcok isTYPE STATES IS(ST0,ST1,ST2,ST3,ST4,ST5,ST6,ST7);SIGNAL CURRENT_STATE,NEXT_STATE:STATES:=ST0;SIGNAL REGL : STD_LOGIC_VECTOR(7 DOWNTO 0);SIGNAL REG : STD_LOGIC_VECTOR(15 DOWNTO 0):="0000000000000000"; SIGNAL LOCK : STD_LOGIC;signal cclk,clkseg:std_logic;signal s : std_logic_vector(1 downto 0):="00";signal digit : std_logic_vector(3 downto 0);signal aen : std_logic_vector(3 downto 0);signal qat,qbt,qct,qdt: STD_LOGIC_VECTOR (3 downto 0);signal b : STD_LOGIC_VECTOR (13 downto 0):="00000000000000"; signal p : STD_LOGIC_VECTOR (16 downto 0):="00000000000000000"; beginADDA<="000";--LOCK1<=LOCK;clockout <=cclk;REG(7 DOWNTO 0) <= REGL;Q<=REGL;dp<='0';aen(0)<=qdt(3) or qdt(2) or qdt(1) or qdt(0);aen(1)<=qdt(3) or qdt(2) or qdt(1) or qdt(0) or qct(3) or qct(2) or qct(1) or qct(0);aen(2)<=qdt(3) or qdt(2) or qdt(1) or qdt(0) or qct(3) or qct(2) or qct(1) or qct(0) or qbt(3) or qbt(2) or qbt(1) or qbt(0);aen(3)<='1';b(7 downto 0)<=REGL(7 DOWNTO 0);------------------------------------------qat <= P(3 downto 0);qbt <= P(7 downto 4);qct <= P(11 downto 8);qdt <= "0000";------------------------------------------process(b)variable z : std_logic_vector(32 downto 0);beginfor i in 0 to 32 loopz(i):='0';end loop;z(16 downto 3) := b;for j in 0 to 10 loopif(z(17 downto 14)>"0100") thenz(17 downto 14):= z(17 downto 14) + "0011";end if;if(z(21 downto 18)>"0100") thenz(21 downto 18):= z(21 downto 18) + "0011";end if;if(z(25 downto 22)>"0100") thenz(25 downto 22):= z(25 downto 22) + "0011";end if;if(z(29 downto 26)>"0100") thenz(29 downto 26):= z(29 downto 26) + "0011";end if;z(32 downto 1):=z(31 downto 0);end loop;p<=z(30 downto 14);end process;PROCESS(CLK)VARIABLE q:INTEGER:=0;BEGINIF CLK'EVENT AND CLK='1' THENq:=q+1;IF q<=199 THEN clkseg<='0';ELSIF q<399 THEN clkseg<='1';ELSE q:=0;END IF;END IF;END PROCESS;-------------------------------------------- PROCESS(CLK)VARIABLE q4:INTEGER:=0;BEGINIF CLK'EVENT AND CLK='1' THENq4:=q4+1;IF q4<=49 THEN cclk<='0';ELSIF q4<99 THEN cclk<='1';ELSE q4:=0;END IF;END IF;END PROCESS;------------------------------------------------- PROCESS(cclk)BEGINIF(cclk'EVENT AND cclk='1') THENCURRENT_STATE<=NEXT_STATE;END IF;END PROCESS;--------------------------------------------- PROCESS(LOCK)BEGINIF LOCK='1' AND LOCK' EVENT THEN REGL<=D;END IF;END PROCESS;------------------------------process(CURRENT_STATE,EOC)BEGINCASE CURRENT_STATE ISWHEN ST0=>ALE<='0';START<='0';OE<='0';LOCK<='0';NEXT_STATE<=ST1;WHEN ST1=>ALE<='1';START<='0';OE<='0';LOCK<='0';NEXT_STATE<=ST2;WHEN ST2=>ALE<='1';START<='1';OE<='0';LOCK<='0';NEXT_STATE<=ST3;WHEN ST3=>ALE<='0';START<='1';OE<='0';LOCK<='0';NEXT_STATE<=ST4;WHEN ST4=>ALE<='0';START<='0';OE<='0';LOCK<='0';IF(EOC='1')THEN NEXT_STATE<=ST4;ELSE NEXT_STATE<=ST5;END IF;WHEN ST5=>ALE<='0';START<='0';OE<='0';LOCK<='0';IF(EOC='0')THEN NEXT_STATE<=ST5;ELSE NEXT_STATE<=ST6;END IF;WHEN ST6=>ALE<='0';START<='0';OE<='1';LOCK<='0';NEXT_STATE<=ST7;WHEN ST7=>ALE<='0';START<='0';OE<='1';LOCK<='1';NEXT_STATE<=ST0;WHEN OTHERS=>ALE<='0';START<='0';OE<='0';LOCK<='0';NEXT_STATE<=ST0;END CASE;END PROCESS ;------------------------------------------------------------------ process(s,qat,qbt,qct,qdt)begincase s iswhen"00" =>digit<=qdt(3 downto 0);when"01" =>digit<=qct(3 downto 0);when"10" =>digit<=qbt(3 downto 0);when"11" =>digit<=qat(3 downto 0);when others =>null;end case;end process;-------------------------------------------------------------------------- process(digit)begincase digit iswhen x"0" => seg7 <= "1111110";--"0000001";when x"1" => seg7 <= "0110000";--"1001111";when x"2" => seg7 <= "1101101";--"0010010";when x"3" => seg7 <= "1111001";--"0000110";when x"4" => seg7 <= "0110011";--"1001100";when x"5" => seg7 <= "1011011";--"0100100";when x"6" => seg7 <= "1011111";--"0100000";when x"7" => seg7 <= "1110000";--"0001111";when x"8" => seg7 <= "1111111";--"0000000";when x"9" => seg7 <= "1111011";--"0000100";when x"A" => seg7 <= "1110111";--"0001000";when x"B" => seg7 <= "0011111";--"1100000";when x"C" => seg7 <= "1001110";--"0110001";when x"D" => seg7 <= "0111101";--"1000010";when x"E" => seg7 <= "1001111";--"0110000";when others => seg7 <= "1000111";--"0111000";end case;end process;-------------------------------------------------------------------------- process(aen,s)beginan<="0000";if(aen(conv_integer(s))='1') thenan(conv_integer(s))<='1';end if;end process;-------------------------------------------------------------------------- process(clkseg)beginif(rising_edge(clkseg)) thens<=s+"01";end if;end process;end Behavioral;--引脚配置文件#PACE: Start of Constraints generated by PACE#PACE: Start of PACE I/O Pin AssignmentsNET "CLK" LOC = "p80" ;NET "ADDA<0>" LOC = "p147" ;NET "ADDA<1>" LOC = "p145" ;NET "ADDA<2>" LOC = "p140" ;NET "ALE" LOC = "p146" ;NET "clockout" LOC = "p119" ;NET "D<0>" LOC = "p132" ;NET "D<1>" LOC = "p128" ;NET "D<2>" LOC = "p126" ;NET "D<3>" LOC = "p122" ;NET "D<4>" LOC = "p133" ;NET "D<5>" LOC = "p129" ;NET "D<6>" LOC = "p127" ;NET "D<7>" LOC = "p123" ;NET "EOC" LOC = "p150" ;NET "OE" LOC = "p138" ;NET "Q<0>" LOC = "p33" ;NET "Q<1>" LOC = "p31" ;NET "Q<2>" LOC = "p30" ;NET "Q<3>" LOC = "p29" ;NET "Q<4>" LOC = "p28" ;NET "Q<5>" LOC = "p25" ;NET "Q<6>" LOC = "p24" ;NET "Q<7>" LOC = "p23" ;NET "START" LOC = "p139" ;NET "an<0>" LOC = "p39" ;NET "an<1>" LOC = "p36" ;NET "an<2>" LOC = "p35" ;NET "an<3>" LOC = "p34" ;NET "dp" LOC = "p40" ;NET "seg7<0>" LOC = "p49" ;NET "seg7<1>" LOC = "p42" ;NET "seg7<2>" LOC = "p45" ;NET "seg7<3>" LOC = "p41" ;NET "seg7<4>" LOC = "p48" ;NET "seg7<5>" LOC = "p50" ;NET "seg7<6>" LOC = "p47" ;#PACE: Start of PACE Area Constraints#PACE: Start of PACE Prohibit Constraints#PACE: End of Constraints generated by PACE。

FPGA控制AD转换原理及程序

FPGA控制AD转换原理及程序

基于FPGA的AD控制模块(2010-07-23 18:00:42)转载▼分类:技术标签:杂谈这是夏天小学期做的第一个课程设计。

题目是《模拟信号处理》,实质上就是做一个对ADC0809的控制器,控制AD转换并读取出转换结果,将结果显示为10进制数。

ADC0809是单通道输入,8位输出的模/数转换器。

参考电压为2.560V时最小分辨率为0.020V。

关于ADC0809的时序控制图如下:信号说明(对ADC0809而言):rd是输入信号,功能是读转换结果使能,当rd为高电平时数据端输出为高阻态,低电平时数据端输出数据。

wr是输入信号,功能是转换开始与结果清除,当wr由低变高时,AD转换开始,当wr由高变低时,转换结果清除,rd信号有效时wr必须为高才是有效数据。

int是输出信号,功能是AD转换完成的中断信号,高AD转换完成后,ADC0809自动输出int信号,即int由高变低,转换过程中,int一直为高电平。

clk 为输入时钟信号。

此外还有一个片选信号CS,低电平有效,当CS信号有效时,ADC0809允许工作。

AD转换的时序控制最优方案是使用有限状态机(FSM),在有int中断信号时,使用状态机控制开始后被动等待int下降沿到来,然后进入读数据状态。

有些情况下int中断信号是悬空的没有使用,这时需要主动控制转换等待时间。

ADC0809的典型转换时间是135us。

主动等待的效率很低,且时序配合一定要准确。

以下是状态机的参考程序:moduleadcfsm(int_adc,clk,reset,rd_adc,wr_adc);outputrd_adc,wr_adc;inputint_adc,clk,reset;regrd_adc,wr_adc;reg[1:0]present;parameterreset_ad=2'h0,start_ad=2'h1,wait_ad=2'h2,read_ad=2'h3;always @(posedgeclk or negedge reset)if(!reset)present<=reset_ad;else if(rd_adc==1&wr_adc==0)present<=start_ad;else if(rd_adc==1&wr_adc==1&int_adc==0)present<=read_ad;else if(rd_adc==1&wr_adc==1)present<=wait_ad;else present<=reset_ad;always @(present)begincase(present)reset_ad:beginrd_adc<=1;wr_adc<=0;endstart_ad:beginrd_adc<=1;wr_adc<=1;endwait_ad:beginrd_adc<=1;wr_adc<=1;endread_ad:beginrd_adc<=0;wr_adc<=1;endendcaseendendmoduleAD转换后的结果为8位二进制数据,即00H~FFH,要输出到数码管上显示,需要将二进制码转换为8421BCD码。

数字电路实验三:数字电压表(设计报告)

数字电路实验三:数字电压表(设计报告)

数字电路实验三:数字电压表(设计报告)数电实验3设计报告实验名称:数字电表实验目的:1.掌握组合逻辑与时序逻辑电路的设计方法及调试方法2.熟练掌握常用MSI逻辑芯片的功能及使用方法3.初步掌握Verilog HDL数字系统设计方法4.熟悉PLD实验箱的结构和使用及Quartus II软件的基本操作5.掌握采用Quartus II软件和实验箱设计实现逻辑电路的基本过程设计任务及要求:1、利用FPGA 与ADC0809 设计一个数字电压表,能够测量0-5V 之间的直流电压值,四位数码显示。

2、在实验电路板上焊接插座,将ADC0809 安装在插座上。

3、选择一路模拟量输入通道(如:IN0),经可调电位器送入0-5V 的直流电压。

4、ADC0809 时序由FPGA 控制,ADC 转换输出的数字量(D7-D0)送回FPGA,转换结果由实验箱上的LED 数码管以十进制形式显示。

5、ADC0809 的VREF 接+5V 电压。

6、FPGA 与ADC0809 之间接口利用实验箱上的“彩色液晶”接口。

程序设计过程:1、定义程序名、输入输出量和初始化Moduleadc_cc(clkin,rst,clkout,sel,data,start,eoc,ale,oe,seg_com,seg_data); input clkin; //时钟输入50MHZ inputrst;inputeoc; //ADC0809input [7:0] data; //输入八位数据output clkout; //时钟输出output start; //ADC0809起始信号 output [2:0] sel;//转换通道 output ale; //ADC0809 outputoe;//ADC0809 output [7:0] seg_com; //位选 output [7:0] seg_data;//段选parameter CLK_FREQ = 'D50_000_000;//系统时钟50MHZ parameter CLK_out_FREQ ='D500_000;//输出时钟parameter state_pre = 0; //sel 状态1parameter state_pre2 = 1; //ale 状态2 parameter state_start =2; //start 状态3 parameter state_conv = 3; //conv 状态4parameter state_wait = 4; // 状态5 parameter state_readpre = 5;// 状态6 parameter state_read = 6;//over // 状态7reg [2:0] sel; //定义寄存器 reg ale;//定义寄存器 reg start; //定义寄存器 regoe; //定义寄存器reg [7:0] data_led; //LED显示数据 reg[31:0] DCLK_DIV; //32位计数器regclkout; //提供ADC0809时钟500KHZ reg [3:0]state = state_pre;2、按照PDF所给出的时序图进行编程对照时序图,使ADC0809按上图方式工作进行编程always @ (negedgeclkout) case (state) state_pre : begin sel[2:0] <='b000; //ABC 000 通道0 state <= state_pre2;//转到状态2 oe<= 0; //OE拉低 end state_pre2 :begin ale <= 1; state <= state_start; endstate_start : begin start <= 1; ale<= 0; state <=state_conv; end state_conv : begin ale <= 0;start <= 0; state <= state_wait; end state_wait :begin if(eoc) begin state <= state_readpre; endend state_readpre : begin oe<= 1; state <= state_read; end state_read : begin data_led = data; state <= state_pre; end endcase//ALE拉高 //转到状态3 //START拉高 //转到状态4//ALE拉低锁定 //START拉低 AD启动 //转到状态5 //查询EOC是否被拉高 //转到状态6 //输出使能拉高 //转到状态7//开始读数据 //重新回到状态1 进行下一次AD转换 3、将AD转换结果用数码管显示。

基于FPGA和adc0809的数字电压表的设计

基于FPGA和adc0809的数字电压表的设计

基于FPGA的数字电压表的设计0 引言传统的数字电压表设汁通常以大规模ASIC(专用集成电路)为核心器件,并辅以少量中规模集成电路及显示器件构成。

ASIC完成从模拟量的输入到数字量的输出,是数字电压表的心脏。

这种电压表的设计简单、精确度高,但是这种设计方法由于采用了ASIC器件使得它欠缺灵活性,其系统功能固定,难以更新扩展。

后来发展起来的用微处理器(单片机)控制通用A/D转换器件的数字电压表的设计的灵活性明显提高,系统功能的扩展变得简单,但是由于微处理器的引脚数量有限,其控制转换速度和灵活性还是不能满足日益发展的电子工业的需求。

而应用EDA(电子设汁自动化)技术及FPGA(现场可编程门阵列),其集成度高、速度快、性能十分可靠、用户可自由编程且编程语言通俗易懂、系统功能扩展非常方便[1]。

采用FPGA芯片控制通用A/D转换器可使速度、灵活性大大优于由微处理器和通用A/D转换器构成的数字电压表。

1 系统设计原理本设计利用ADC0809作为电压采样端口,FPGA作为系统的核心器件,用LED(发光二极管)进行数码显示。

采用Alterla公司FLEX10K系列EPF10K20TC144-4芯片FPGA作为系统的核心器件,负责ADC0809的A/D转换的启动、地址锁存、输入通道选择、数据读取。

同时,把读取的8位二进制数据转换成便于输出的3位十进制BCD码送给数码管,以显示当前测量电压值。

这些工作由ADC0809转换控制模块、数据转换模块、译码模块完成。

2 FPGA软件设计及模块仿真2.1 A/D转换控制模块的软件设计本模块完成ADC0809的初始化、A/D转换的启动、地址锁存、通道选择、状态读取及数据读取、数据锁存等功能。

此模块的软件设计主要采用VHDL的多进程状态机完成[4]。

工作时序如下:上电瞬问,FPGA初始化,ADD置成"01",状态机处于第1个状态,此时ALE、START、OE、LOCK(数据锁存信号)均置0,初始化ADC0809。

adc0809fpga点正显示

adc0809fpga点正显示

adc0809fpga点正显示library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_*****D.ALL;ENTITY ad0809 ISPORT (clk,int : in std_logic; --时钟输入cs,wr,rd : out std_logic; ---AD控制信号tongdao :buffer std_logic_vector(1 DOWNTO 0); --通道选择信号selout : out std_logic_vector(1 DOWNTO 0); --位选输出datout : out std_logic_vector(15 DOWNTO 0) ); --段码输出END ad0809 ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------architecture arch of ad0809 istype state is (s0,s1,s2,s3);---状态定义signal current_state,next_state : state ;signal cnt :std_logic_vector(2 DOWNTO 0);signal sel :std_logic_vector(1 DOWNTO 0);signaltongdao1,tongdao2,tongdao3,tongdao4:std_logic_vector(7 DOWNTO 0);signal tmp :std_logic_vector(7 DOWNTO 0);signal flag :std_logic;beginprocess(current_state)begincase current_state iswhen s0 = cs='1';wr='1'; rd='0';flag= '0'; next_state = s1;when s1 = cs='0';wr='0'; rd='0'; flag= '0'; if int ='1' thennext_state= s2;elsenext_state= s1;end if;when s2 = cs='1';wr='0';rd='1';flag= '1'; --当flag=1时开始采集数据next_state= s3;when s3 = cs='0';wr='0';rd='0';flag= '0';next_state= s0;end case;end process;process (clk)beginif (clk'event and clk='1') thencurrent_state=next_state; ---状态转换end if; end process;process(flag)beginif flag'event and flag='1' thentongdao= tongdao+1; --通道加1sel= sel+1; --位选加一case tongdao iswhen “00" = tongdao1=data; ---将对应通道值送出when "01" = tongdao2=data;when "10" = tongdao3=data;when "11" = tongdao4=data;when others = null;end case;------------------每个通道所对应的位选case sel iswhen "00" = tmp=tongdao1; --将对应值送给tmp,进行输出处理when "01" = tmp=tongdao2;when "10" = tmp=tongdao3;when "11" = tmp=tongdao4;when others = null;end case;selout=sel;end if;end process;process(sel)begincase tmp is ---将转换得来的值处理,并选择相应输出数据when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ;when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when "***-*****" = datout="***-********-*****" ; when others = null;end case;end process;end arch;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;---______--clk--______entity adc isport( clk:in std_logic;wr,rd,cs:out std_logic; --外部时钟输入int:in std_logic; --数据转换完成dat:in std_logic_vector(7 downto 0); --AD数据输入sel:out std_logic_vector(3 downto 0); --点阵位选datout:out std_logic_vector(15 downto 0)); --点阵段选end entity;--______--______architecture behave of adc istype states is( s0,s1, s2, s3);signal datin:std_logic_vector(7 downto 0); --输入数据signal current_state,next_state:states:=s0; --现态和次态signal eoc:std_logic; --转换完成标志signal cnt:std_logic_vector(1 downto 0); -- 计数--__状态转换____ begineoc=int;qdadc:process(current_state,eoc)begincase current_state iswhen s0= next_statecs='1';wr='1';rd='0';when s1= cs='0';wr='0';rd='0';if eoc='1' thennext_state --如果转换完成则条到下一个状态elsenext_state--否则将继续上一个状态等待end if;when s2=next_statecs='1';wr='0';rd='1';datin=dat; --转换完成接受数据when s3=next_statecs='0';wr='0';rd='0';when others= next_statecs='1';wr='1';rd='0';end case;end process;fenpin:process(clk)beginif clk'event and clk='1' thenif cnt="11" thencurrent_state=next_state; --将次态给现态的值else cnt=cnt+1;end if;end if;end process;dataa=datin;--____显示______disp: blockbeginwith datin(7 downto 4)select ---对高四位数值进行判断datout="***-********-*****" when"0000","***-********-*****" when"0001","***-********-*****" when"0010","***-********-*****" when"0011","***-********-*****" when"0100","***-********-*****" when"0101","***-********-*****" when"0110","***-********-*****" when"0111","***-********-*****" when"1000","***-********-*****" when"1001","***-********-*****" when"1010","***-********-*****" when"1011","***-********-*****" when"1100","***-********-*****" when"1101","***-********-*****" when"1110","***-********-*****" when"1111","***-********-*****" when others;sel="0001";end block;--______end behave;library ieee; 译码use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;---______--clk系统时钟,sel位选datout:段码输出--______entity adc isport( clk:in std_logic;wr,rd,cs:out std_logic;int:in std_logic;dat:in std_logic_vector(7 downto 0);sel:out std_logic_vector(3 downto 0); datout:out std_logic_vector(15 downto 0)); end entity;--______--______architecture behave of adc istype states is( s0,s1, s2, s3); --状态表signal datin:std_logic_vector(7 downto 0);--输入数据signal current_state,next_state:states:=s0;--现态,下一个状态signal eoc:std_logic;signal sel_dat:std_logic_vector(3 downto 0);--位选译码变量signal temp:std_logic_vector(4 downto 0);--译码中间值--______--____ad转换---------------------------begineoc=int;qdadc:process(current_state,eoc)begincase current_state iswhen s0= next_statecs='1';wr='1';rd='0';when s1= cs='0';wr='0';rd='0';if eoc='1' thennext_state --如果转换成功,跳到下一个状态next_state--为转换成功,则继续等待end if;when s2=next_statecs='1';wr='0';rd='1';datin=dat; when s3=next_statecs='0';wr='0';rd='0';when others= next_statecs='1';wr='1';rd='0';end case;end process;---________---__状态转换和译码____ zhuantai:process(clk) beginif clk'event and clk='1' thencurrent_state=next_state;---状态变换sel_dat=sel_dat-1; ----产生列扫描值sel=sel_dat;if(datin(7 downto 4)sel_dat) thentemp="01111";elsif(datin(7 downto 4)=sel_dat)thentemp='0'datin(3 downto 0);elsetemp="*****";end if;end process;--________ --temp由--____显示部分____ disp: blockbeginwith temp selectdatout="***-********-*****" when"00000", "***-********-*****" when"00001","***-********-*****" when"00010","***-********-*****" when"00011","***-********-*****" when"00100","***-********-*****" when"00101","***-********-*****" when"00110","***-********-*****" when"00111","***-********-*****" when"01000","***-********-*****" when"01001","***-********-*****" when"01010","***-********-*****" when"01011","***-********-*****" when"01100","***-********-*****" when"01101","***-********-*****" when"01110", "***-********-*****" when"01111", "***-********-*****" when others;。

FPGA设计-ADC0809

FPGA设计-ADC0809

FPGA设计-ADC0809目录摘要 (3)1设计任务 (6)2系统设计原理 (6)2.1 硬件设计原理 (6)2.1.1 ADC0809的主要特性 (6)2.1.2 ADC0809的外部特性 (6)2.1.3工作过程 (7)2.2 软件设计思路 (8)2.3 程序流程图 (9)3功能与时序仿真 (10)3.1 功能仿真得出的RTL图 (10)3.2 功能仿真得出的状态图 (11)3.3 时序仿真 (12)4总结 (12)5参考文献 (13)附录一程序 (14)摘要实现时必须严格遵守ADC0809的工作时序,对选定的通道输入一个模拟量,调节电位器改变输入的模拟量。

利用quartus2进行文本编辑输入和试仿;给出仿真波形。

最后进行引脚锁定并进行测试,硬件验证ADC0809 的控制功能。

具体过程为:编写ADC0809时序的VHDL代码。

对其进行编译仿真主要控制信号为:Start为转换启动信号,高电平有效;ale为通道选择地址信号的锁存信号。

当启动转换后,程序开始执行,查询状态,状态为0.1.时等待,状态2时,查询EOC信号的状态,判断是否转换结束,当EOC=1时表示转换结束,否则继续等待;转换结束后继续查询状态,若OE信号为高电平则控制打开三态缓冲器,当LOCK信号为高电平时,将转换后的数据进行锁存,至此一次转换结束。

关键词:工作时序、AD0809 、VHDL、quartus2、编译仿真、Start 、EOC、OE、三态缓冲器1设计任务基于VHDL语言,实现对ADC0809简单控制。

2系统设计原理2.1 硬件设计原理ADC0809 为单极性输入,8位转换逐次逼近A/D转换器,可对0~5V的INT0~INT7的8路模拟电压信号分时进行转换,完成一次转换的时间为100 微秒。

ADD-CBA作为8路通道选择地址,在转换开始前由地址锁存允许信号ALE 将3位地址锁入锁存器中,以确定转换信号通道;EOC为状态结束标志,低电平转为高电平时转换结束;START为转换启动信号,上升沿有效;OE为数据输出允许端,高电平有效;〔D0⋯D7〕为A/D变换数据输出端。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
reg START,OE,ALE,ADDA;
reg[7:0] DATA_R;
reg[4:0] CS,NS;
parameter IDLE=5'b00001,START_H=5'b00010,START_L=5'b00100,CHECK_END=5'b01000,GET_DATA=5'b10000;
always @(posedge clk500K)
always @(posedge clk500K)
if(!rst_n)
CS<=IDLE;
else
CS<=NS;
always @(posedge clk500K)
case(NS)
IDLE:
begin
OE<=0;
START<=0;
ALE<=0;ADDA<=1;
end
START_H:
begin
OE<=0;
ALE, //高电平有效,选择信道口
ADDA, //因为ADDB,ADDC都接地了,这里只有ADDA为变量
DATA, //转换数据
DATA_R);
output START,OE,ALE,ADDA;
input EOC,clk500K,rst_n;
input[7:0] DATA;
output[7:0] DATA_R;
若参考电压为0-1V
(1-0)/255≈0.0039V精度自然高了。。可测量范围小了。
状态机要写成3段式的(这是最标准的写法),即
...
always @(posedge clk or negedge rst_n)
...
current_state <= next_state;
...
always @ (current_state ...)
/*FPGA实现的程序:(verilog)
贴子回复于:2008-4-27 15:26:01*/
module AD0809(clk500K, //脉宽(至少100ns)
rst_n,
EOC, //约100us后EOC变为高电平转换结束
START, //启动信号,上升沿有效(至少100ns)
OE, //高电平打开三态缓冲器输出转换数据
...
case(current_state)
...
s1:
if ...
next_state = s2;
...
...
always @(posedge clk or negedge rst_n)
...
else
a <= 1'b0;
c <= 1'b0;
c <= 1'b0; //赋默认值
case(current_state)
参考电压为0-5V的话。以0809八位255的转换精度每一位的电压值为(5-0)/255≈0.0196V
设输入电压为X则:
X-27*0.0196>=0则AD7=1否则AD7=0。
X-26*0.0196>=0则AD6=1否则AD6=0。



X-20*0.0196>=0则AD0=1否则AD0=0。
(27指2的7次方。26-------20同理)
s1:
a <= 1'b0; //由于上面赋了默认值,这里就不用再对b
、c赋值了(b、c在该状态为0,不会产生锁存器,下同)
s2:
b <= 1'b1;
s3:
c <= 1'b1;
default:
...
...
GET_DATA:
begin
OE<=1; //高电平打开三态缓冲器输出转换数据
DATA_R<=DATA;//提取转换数据
START<=0;
ALE<=0;
end
default:
begin
OE<=0;
START<=0;
ALE<=0;
ADDA<=0;
end
endc位逼近的方法产生数据的。。
START<=1; //产生启动信号
ALE<=1;
ADDA<=1;//选择信道口IN0
end
START_L:
begin
OE<=0;
START<=0;
ALE<=1;//启动信号脉宽要足够长,在启动的时候ALE要一直有效
end
CHECK_END:
begin
OE<=0;
START<=0;
ALE<=0;
end
case(CS)
IDLE:
NS=START_H;
START_H:
NS=START_L;
START_L:
NS=CHECK_END;
CHECK_END:
if(EOC)
NS=GET_DATA;
else
NS=CHECK_END;
GET_DATA:
NS=IDLE;
default:
NS=IDLE;
endcase
相关文档
最新文档