ADC0809驱动FPGA实现的verilog程序
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的采样电路设计

实验六用状态机实现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接口电路详解注:(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采样电路设计

实验用状态机实现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对模拟信号进行采样.

第二章总体方案设计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点正显示

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采样控制器设计

© 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与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组件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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