用状态机控制ADC0809实现A/D转换。
如下图所示为状态机控制ADC0809的结构框图。
图1 采样状态机结构框图用状态机对ADC0809进行采样控制,首先必须了解其工作时序,然后据此作出状态图,最后写出相应的Verilog代码。
ADC0809是8位CMOS A/D转换器,片内有8路模拟开关,可控制8个模拟量中的一个进入转换器中。ADC0809的分辨率为8位,转换时间约100us,含锁存控制的8路多路开关,输出有三态缓冲器控制,单5V电源供电。
如图2所示为ADC0809工作时序及引脚图。
图2 ADC0809工作时序及引脚图如图2所示,下面对ADC0809工作时序稍加解释。
(1)START为转换启动控制信号,高电平有效;
(2)ALE为模拟信号输入选通端口地址锁存信号,上升沿有效;
(3)START信号有效后,状态信号EOC即变为低电平,表示进入转换状态,转换时间约100us。转换结束后, EOC变为高电平,控制器据此可了解转换情况。
(4)外部控制可以使OE由低电平变为高电平(输出有效),此时0809的输出数据总线D[7:0]从原来的高阻态变为输出数据有效。
根据ADC0809工作时序,可以作出控制ADC0809采样状态图,如图3所示。
图3 控制ADC0809采样状态图如图3所示,下面对各状态稍加解释。
st0:对0809初始化;
st1:由START、ALE发出启动采样和地址选通的控制信号,EOC由高电平变 为低电平,0809的8位数据输出端呈现高阻态“ZZ”;
st2:采样周期中等待,等待了几个时钟周期后,EOC变为高电平,表示转换结束;
st3:状态的输出允许OE被设置成高电平,此时0809的数据输出端D[7:0] 输出已经转换好的数据;
st4:LOCK发出一个脉冲,其上升沿立即将D端口的数据锁入Q和REGL中。
控制ADC0809采样的状态机源代码,如下所示。
module control(CLK,D,EOC,RST,ALE,START,OE,ADDA,Q,LOCK_T,cs_1);//cs_1
input[7:0] D; //来自ADC0809转换好的8位数据(8位二进制数)
input CLK,RST; //状态机工作时钟和系统复位信号
input EOC; //转换状态指示,低电平表示正在转换
output reg ALE; //8个模拟信号通道地址锁存信号
output reg START,OE; //转换启动信号和数据输出三态控制信号
output[3:0] cs_1;
output ADDA,LOCK_T; //信号通道控制信号和锁存测试信号
output[7:0] Q;
parameter s0=0,s1=1,s2=2,s3=3,s4=4; //定义各状态子类型
reg[4:0] cs,next_state; //为了便于仿真显示,现状态变量名简写为cs
reg[7:0] REGL; //转换后数据锁存输出
reg LOCK; //转换后数据输出锁存时钟信号
always@(posedge CLK or posedge RST) //时序过程
begin
if(RST) cs<=s0;
else cs<=next_state; //由现态变量cs将当前状态值带出过程
end
always@(cs or EOC) //组合过程
begin
case(cs)
s0:begin ALE<=0;START<=0;OE<=0;LOCK<=0;next_state<=s1; end //ADC0890初始化
s1:begin ALE<=1;START<=1;OE<=0;LOCK<=0;next_state<=s2; end //启动采样信号START
s2:begin ALE<=0;START<=0;OE<=0;LOCK<=0;
if(EOC==1'b1) next_state<=s3; //EOC=1表明转换结束
else next_state<=s2; //转换未结束,继续等待
end
s3:begin ALE<=0;START<=0;OE<=1;LOCK<=0;next_state<=s4; end //开启OE,打开ADC数据口
s4:begin ALE<=0;START<=0;OE<=1;LOCK<=1;next_state<=s0; end //开启数据锁存信号
default:begin ALE<=0;START<=0;OE<=0;LOCK<=0;next_state<=s0; end
endcase
end
always@(posedge LOCK) //寄存器过程
begin
REGL<=D; //在LOCK上升沿将转换好的数据锁入
end
assign ADDA=0; //选择模拟信号进入通带IN0
assign Q=REGL;
assign LOCK_T=LOCK; //将测试信号引出
assign cs_1=cs; //将状态信号引出
endmodule
强调:因为本次实验牵扯到两个芯片,要理解对ADC0809来说是输入/输出,对状态机而言是输出/输入。
仿真:为了在仿真波形中看到当前状态cs的变化情况,可以增设输出cs_1,然后用 assign cs_1=cs语句,将当前状态cs的值赋给输出即可。如图4所示为控制器的仿真波形。
图4 控制器的仿真波形
1 )选择宏功能模块PLL-Altera PLL v13.1,为该定制宏功能模块取名为PLL50,如图5所示。
图5 定制锁相环宏功能模块2) 在生成的Altera PLL页面,在general页面做如下设置,如图6所示。点击finish按钮后,找到PLL50模块。
图6 宏功能模块锁相环设置
3) PLL50设置完成之后,打开PLL50.v文件,用Create/Update命令,生成其Symbol文件。
ADC0809采样控制电路顶层设计如图7所示。
图7 ADC0809控制器顶层设计其中,控制器的工作时钟为5MHz,ADC0809的工作时钟为750KHz。
该实验可以选择电路模式5,使用ADC0809扩展模块,如图8所示。需注意:该扩展模块如果插在主系统上使用,要选择主系统的带+-12V的的插座,比如我们实验箱的实验模块3。
引脚锁定:
图8 双通道DAC和ADC标准模块其中:标注“2”是ADC0809的模拟输入通道。标注“3”是ADC0809通道“IN0”输入的选择钮,可通过此按钮输入电压信号。因此在这个实验中我们只能通过IN0口给ADC0809输入模拟信号。标注“4”是0809的控制端口,其中有一个“CLK”端,是FPGA向0809的输入时钟端。标注“5”是0809的数据输出端。
要求:测出输出Q[7:0]分别为20、40、60、80、A0、C0、E0和FF时IN0口输入的模拟电压值,找到输入模拟电压值和输出数字量之间的关系,算出比例系数。测试方法为,测量ADC0809的26脚IN0和13脚GND之间的电压。