具有FIFO的AD采样控制电路设计.docx
《具有FIFO的AD采样控制电路设计.docx》由会员分享,可在线阅读,更多相关《具有FIFO的AD采样控制电路设计.docx(17页珍藏版)》请在冰豆网上搜索。
具有FIFO的AD采样控制电路设计
一、概述
1.1A/D转换的基本概念
随着数字技术飞速发展与普及,在现代控制、通信及检测等领域,为了提高系统的性能指标,对信号的处理广泛采用了数字技术。
由于系统的实际对象往往都是一些模拟量(如温度、压力、位移、图像等),要使系统能识别和处理这些信号,必须将这些模拟信号转换成数字信号;这样,就需要一种能在模拟信号与数字信号之间起桥梁作用的电路-A/D转换器。
将模拟信号转换成数字信号的电路,称为模数转换器(简称A/D转换器);A/D转换器已成为信息系统中不可缺少的接口电路。
为确保系统处理结果的精确度,A/D转换器必须具有足够的转换精度;如果要实现快速变化信号的实时控制与检测,A/D转换器还要求具有较高的转换速度。
转换精度与转换速度是衡量A/D转换器的重要技术指标。
此次课程设计则是利用ADC0809来进行A/D转换,并将转换好的数据锁存到FIFO中,通过外部按键控制FIFO写入和读出数据。
1.2有限状态机的基本概念
有限状态机又称有限状态自动机或简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
状态机分成两大类:
Melay型和Moore型状态机;
Melay型状态机的输出是当前状态和所有输入信号的函数。
其输出是输入变化后立即发生变化。
Moore型的输出仅是当前状态的函数。
其在输入发生变化后,还需等待时钟的到来,只有时钟使状态发生变化才导致输出变化。
因此要多等待一个时钟周期。
在运用状态机时,首先要自定义数据类型,然后再通过说明部分、主控时序进程、主控组合进程以及辅助进程来实现所需实现的功能。
说明部分中有新数据类型TYPE的定义及其状态类型以及在此新类型下定义的状态变量。
状态变量应该定义为信号,便于信息传递。
而主控时序进程则是一个对工作时钟信号敏感的进程,该进程作为状态机的“驱动泵”,当时钟发生有效跳变时,状态机状态才发生变化。
主控组合进程的任务是根据控制信号或(和)当前状态的状态值确定下一状态next_state的取向,即next_state的取值内容,以及确定对外输出或对内部其它组合或时序进程输出控制信号的内容。
辅助进程则是用于对其他电路功能的控制及实现。
二、设计方案
2.1具有FIFO的A/D控制设计方法
本课程的设计要求:
1、用FPGA对ADC0809进行控制使之完成对输入信号的采样,控制电路应该输出启动信号,通道选择地址信号的锁存信号,检测ADC0809的转换情况状态信号EOC,输出使能信号OE,读入转换结果,存入FIFO中。
2、FIFO中的数据可以在外界信号的控制下读出,结果在LED数码管中显示
3、ADC0809和LED数码管由GW48-PK2系统提供。
4、FIFO可以利用LPM函数实现。
要将ADC0809转换好的转换好的数字信号锁存入FIFO中,因此电路中必然包括FIFO存储器。
同时,还要通过一个2选1的选择器,来选择FIFO的写使能端Wrreq以及读使能端Rdreq的时钟脉冲,并通过外部按键的控制信号来控制FIFO中的数据写入及读出,通过数码管显示出转换好的数据。
基于这一思路,设计出的电路图如图一所示
图一
2.2用状态机来控制A/D采样
ADC0809为单极性输入、8位转换精度、逐级逼进式A/D转换器,其采样速度为每次转换约100us,它的各引脚功能和工作时序如图二所示
图二
有8个模拟信号输入通道,IN0~IN7;由ADDA、ADDB、ADDC作为此8路通道的选择地址,在转换开始前由地址锁存允许信号ALE将此3位地址锁入锁存器中,以确定转换信号通道;EOC为转换结束状态信号,由低电平转为高电平时指示转换结束,此时可读入转换好的8位数据。
EOC在低电平时,指示正在进行转换:
START为转换启动信号,上升沿启动;OE为数据输出允许,高电平有效;CLK为ADC转换时钟输入端口,为了达到A/D器件的最高转换速度,A/D转换控制器必须包含监视EOC信号的逻辑,一旦EOC从低电平变为高电平,即可将OE置为高电平,然后传送已经转换好的数据到FIFO中。
用Moore型有限状态机控制ADC0809采样的状态图如图三所示
图三
由状态图可知:
sto为对0809的初始化;当start为1时开始进行A/D转换,进入st1状态;在st2中对EOC信号进行检测,若为EOC为0,则继续转换,若为1表示转换结束,转入st3。
此时OE为1,则转入st4,并在lock为高电平时将转换好的数据锁存入FIFO中;
根据状态图可得到采样状态机的结构框图,如图四所示
图四
由状态图及结构框图可以用Vhdl编写程序对ADC0809进行控制,编写的程序如附录一所示;
2.3利用LPM函数来生成FIFO
LPM是参数可设置模块库的英语缩写(LibraryofParameterizedModules)。
库中模块可以用图形或硬件描述语言的形式调用。
设计者根据实际电路需要,选择LPM库中,合适模块,适当设定参数,就可以十分方便的使用优秀电子工程技术人员的设计成果。
使设计的可靠性和效率有很大提高。
FIFO可以利用LPM函数来定制生成,其定制过程如下所示:
在FIFO的定制过程中,还可以定义FIFO中存放8位字节数的个数。
2.42选1控制电路的设计
可以通过2选1控制电路对生成的FIFO进行控制,通过外加的信号来控制FIFO的读和写。
2选1的电路图如图五所示
图五
其中a为输出锁存信号lock0的输入端,b为FIFO的读时钟信号Rdclock输入端,可用key4来改变其输入数据;S为2选1的控制端,可用key5来改变其输入信号,当S为低电平时,y输出a,即lock0(lock0为FIFO的写时钟信号)。
当S为高电平时,输出b,即Rdclock。
用Vhdl编写的2选1控制电路的实验程序如附录二所示;
2.5顶层模块及元件例化的调用
元件例化就是将以前设计的实体作为当前设计的一个元件,然后用Vhdl语句将元件与当前设计之间的连接关系通过顶层模块描述出来。
元件例化元件由两部分组成:
1.元件定义,即将已有的设计定义为当前设计的元件;2.元件与当前设计的连接关系映射语句;
--元件定义语句:
component元件名is
generic(类属表);
port(端口名表);
endcomponent文件名;
--元件例化语句
例化名:
元件名portmap([端口名=>]连接端口名,……);
因此,在顶层模块的编写时,可以应用这种格式来调用各例化的元件,通过顶层模块将各元件组合起来,构成实验所需的电路图。
顶层模块的编写如附录三所示。
三、结果与分析
3.1ADC0809的仿真波形分析
ADC0809的采样状态机工作时序如图六所示
图六
由时序图可知:
当START由低电平变为高电平时开始进行转换,EOC为1时表示转换结束,此时OE也由低电平变为高电平,此时允许输出转换好的数据。
当Lock0变为高电平,将转换好的数据锁存入FIFO中。
此过程结束后,又开始新一轮的转换过程。
3.22选1仿真波形的分析
2选1控制选择器的仿真波形如图七所示
图七
当控制端S为低电平时输出a,即lock0信号,此信号用于FIFO的clock端,即在lock0由低电平转变为高电平时,将转换好的数据锁存入FIFO中,此时要求FIFO的写使能端有效,即为高电平。
当控制端S为高电平时输出b,即Rdclock,此信号也是用于FIFO的clock端,即在Rdclock发生跳变时,读出FIFO中存放的数据,显示在数码管上,此时也要求FIFO的读使能端有效。
3.3FIFO仿真波形的分析
FIFO存储器的仿真波形如图八所示
图八
由图可知,aclr必须保持低电平,才可以对FIFO进行读写,否则FIFO里的数据恒为0。
当wrreq为高电平,写使能端有效,即在clock的时钟上升沿时允许数据写入FIFO中。
wrreq为低电平,数据不能写入FIFO。
当rdreq为高电平时,读使能端有效,即在clock的时钟上升沿时允许数据从FIFO中读出。
而rdreq为低电平时,数据不能从FIFO中读出。
四、结论与心得
五、附录
附录一ADC0809采样控制程序
libraryieee;
useieee.std_logic_1164.all;
entityadcis
port(d:
instd_logic_vector(7downto0);--0809的数据输入
clk:
instd_logic;--clk为采样控制时钟信号
eoc:
instd_logic;--eoc为ADC0809转换状态信号
ale:
outstd_logic;--ale为通道选择地址锁存信号
start:
outstd_logic;--start为转换启动信号
oe:
outstd_logic;--oe为输出使能信号
adda:
outstd_logic;--adda为通道选择低位地址
lock0:
outstd_logic;--观察数据锁存时钟
qq:
outstd_logic_vector(7downto0));--变换数据显示输出
endentityadc;
architecturebehavofadcis
typestatesis(s0,s1,s2,s3,s4);--定义各状态
signalcurrent_state,next_state:
states:
=s0;
signalreal:
std_logic_vector(7downto0);--中间数据信号
signallock:
std_logic;--转换后的数据输出锁存时钟信号
begin
adda<='0';--当adda<='0',模拟信号进入IN0,当adda<='1',则进入IN1
lock0<=lock;qq<=real;
com:
process(current_state,eoc)
begin--规定各个状态转换方式,组合进程
casecurrent_stateis
whens0=>ale<='0';start<='0';oe<='0';lock<='0';next_state<=s1;
--初始态s0向下一状态s1转换,0809采样控制信号初始化
whens1=>ale<='1';start<='1';oe<='0';lock<='0';next_state<=s2;--start=1则转换
whens2=>ale<='0';start<='0';oe<='0';lock<='0';
if(eoc='1')thennext_state<=s3;--eoc=1表明转换结束
elsenext_state<=s2;--eoc=0继续等待转换
endif;
whens3=>ale<='0';start<='0';oe<='1';lock<='0';next_state<=s4;
--开启oe,输出转换好的数据
whens4=>ale<='0';start<='0';oe<='1';lock<='1';next_state<=s0;
whenothers=>next_state<=s0;
endcase;
endprocesscom;
reg:
process(clk)--时序进程
begin
if(clk'eventandclk='1')then
current_state<=next_state;--在时钟上升沿转换至下一个状态
endif;
endprocessreg;--由时钟信号current_state将当前状态值带出此进程
latch:
process(lock)--此进程中,在lock的上升沿,将转换好的数据锁入
begin
iflock='1'andlock'eventthenreal<=d;
endif;
endprocesslatch;
endbehav;
附录二2选1控制选择器
libraryieee;
useieee.std_logic_1164.all;
entityeris
port(a,b,s:
instd_logic;
y:
outstd_logic);
endentityer;
architecturertloferis
signald,e:
std_logic;
begin
d<=aand(nots);e<=band(s);y<=dore;
endarchitecturertl;
附录三顶层模块
libraryieee;
useieee.std_logic_1164.all;
entityadcontrolis
port(key1:
instd_logic;--key1用于fifo的异步清零aclr
key2:
instd_logic;--key2用于控制fifo的rdreq
key3:
instd_logic;--key3用于控制fifo的wrreq
key4:
instd_logic;--key4在fifo进行读时给我一个手动的脉冲
key5:
instd_logic;--key5为二选一的s端口
ma:
outstd_logic;--ma用于显示fifo的full的状态
mb:
outstd_logic;--mb用于显示fifo的empty的状态
c:
instd_logic;--c对应0809的clk信号
e:
instd_logic;--e对应0809的eoc信号
f:
outstd_logic;--f对应0809的ale信号
g:
outstd_logic;--g对应0809的start信号
h:
outstd_logic;--h对应0809的oe信号
j:
outstd_logic;--j对应0809的adda信号
ee:
outstd_logic;--ee对应lock0信号
dd:
instd_logic_vector(7downto0);--dd对应0809的数据输入
qqq:
outstd_logic_vector(7downto0));--用于fifo的输出数据显示
endentityadcontrol;
architecturertlofadcontrolis
componentadc_fifo
port(aclr:
instd_logic;
clock:
instd_logic;
data:
instd_logic_vector(7downto0);
rdreq:
instd_logic;
wrreq:
instd_logic;
empty:
outstd_logic;
full:
outstd_logic;
q:
outstd_logic_vector(7downto0));
endcomponent;
componenter
port(a,b,s:
instd_logic;
y:
outstd_logic);
endcomponent;
componentadc
port(d:
instd_logic_vector(7downto0);
clk:
instd_logic;
eoc:
instd_logic;
ale:
outstd_logic;
start:
outstd_logic;
oe:
outstd_logic;
adda:
outstd_logic;
lock0:
outstd_logic;
qq:
outstd_logic_vector(7downto0));
endcomponent;
signalkk:
std_logic_vector(7downto0);
signallock1:
std_logic;
signallock2:
std_logic;
begin
ee<=lock1;
ui:
erportmap(a=>lock1,b=>key4,s=>key5,y=>lock2);
u2:
adc_fifoportmap(aclr=>key1,rdreq=>key2,wrreq=>key3,full=>ma,
empty=>mb,q=>qqq,data=>kk,clock=>lock2);
u3:
adcportmap(clk=>c,eoc=>e,ale=>f,start=>g,oe=>h,adda=>j,
lock0=>lock1,qq=>kk,d=>dd);
endrtl;
附录四总的实验程序
libraryieee;
useieee.std_logic_1164.all;
entityadcontrolis
port(key1:
instd_logic;key2:
instd_logic;key3:
instd_logic;key4:
instd_logic;key5:
instd_logic;ma:
outstd_logic;
mb:
outstd_logic;c:
instd_logic;e:
instd_logic;
f:
outstd_logic;g:
outstd_logic;h:
outstd_logic;
j:
outstd_logic;ee:
outstd_logic;
dd:
instd_logic_vector(7downto0);
qqq:
outstd_logic_vector(7downto0));
endentityadcontrol;
architecturertlofadcontrolis
componentadc_fifo
port(aclr:
instd_logic;clock:
instd_logic;
data:
instd_logic_vector(7downto0);
rdreq:
instd_logic;wrreq:
instd_logic;
empty:
outstd_logic;full:
outstd_logic;
q:
outstd_logic_vector(7downto0));
endcomponent;
componenter
port(a,b,s:
instd_logic;
y:
outstd_logic);
endcomponent;
componentadc
port(d:
instd_logic_vector(7downto0);
clk:
instd_logic;eoc:
instd_logic;
ale:
outstd_logic;start:
outstd_logic;
oe:
outstd_logic;adda:
outstd_logic;
lock0:
outstd_logic;
qq:
outstd_logic_vector(7downto0));
endcomponent;
signalkk:
std_logic_vector(7downto0);
signallock1:
std_logic;
signallock2:
std_logic;
begin
ee<=lock1;
ui:
erportmap(a=>lock1,b=>key4,s=>key5,y=>lock2);
u2:
adc_fifoportmap(aclr=>key1,rdreq=>key2,wrreq=>key3,full=>ma,
empty=>mb,q=>qqq,data=>kk,clock=>lock2);
u3:
adcportmap(clk=>c,eoc=>e,ale=>f,start=>g,oe=>h,adda=>j,
lock0=>lock1,qq=>kk,d=>dd);
endrtl;
libraryieee;
useieee.std_logic_1164.all;
entityadcis
port(d:
instd_logic_vector(7downto0);
clk:
instd_logic;eoc:
instd_logic;
ale:
outstd_logic;start:
outstd_logic;
oe:
outstd_logic;adda:
outstd_logic;
lock0:
outstd_logic;
qq:
outstd_logic_vector(7downto0));
endentityadc;
architecturebehavofadcis
typestatesis(s0,s1,s2,s3,s4);--定义各状态
signalcurrent_state,next_state:
states:
=s0;
signalreal:
std_logic_vector(7downto0);--中间数据寄存信号
signallock:
std_logic;--转换后的数据输出锁存时钟信号
begin
adda<='0';--当adda<='0',模拟信号进入IN0,当adda<='1',则进入IN1
lock0<=lock;qq<=real;
com:
process(current_state,eoc)
begin--规定各个状态转换方式,组合进程
casecurrent_stateis
whens0=>ale<='0';start<='0';oe<='0';lock<='0';next_state<=s1;--初始化
whens1=>ale<='1';start<='1';oe<='0';lock<='0';next_state<=s2;--start=1则转换
whens2=>ale<='0';start<='0';oe<='0';lock<='0';
if(eoc='1')thennext_state<=s3;--eoc=1表明转换结束
elsenext_state<=s2;--eoc=0继续等待转换
endif;
whens3=>ale<='0';start<='0';oe<='1';lock<='0';next_state<=s4;--允许输出数据
whens4=>ale<='0';start<='0';oe<='1';lock<='1';next_state<=s0;
whenothers=>next_state<=s0;
endcase;
endprocesscom;
reg:
process(clk)--时序进程
begin
if(clk'eventandclk='1')then
cu