这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » Xilinx » Spartan 3E开发板上的ADC程序专帖

共4条 1/1 1 跳转至

Spartan 3E开发板上的ADC程序专帖

高工
2011-04-13 17:08:17     打赏

应网友“只为吸引你”的要求,我帮他写了个Spartan 3E开发板上的ADC的程序,包括程控放大器LTC6912和DAC LTC1407A的接口程序,只做了仿真,还没在板子上跑,请 只为吸引你 和其他感兴趣的网友在板子上调试看看,有什么问题或结果,欢迎反馈。


LTC6912时序


 LTC1407A



仿真结果




仿真软件为Modelsim 6.5c

接口程序
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////

module LTC_ADC( Clk, Rst,
    AMP_nCS, AMP_SHDN, SPI_MOSI,
    SPI_SCK,
    AD_CONV, SPI_MISO
);
input Clk, Rst;
output wire AMP_SHDN;
output reg AMP_nCS, SPI_MOSI;
output reg SPI_SCK;
output reg AD_CONV;
input SPI_MISO;

//---------------------------------------------------------------------------------------------
assign AMP_SHDN = 1'b0;

parameter AMP_GAIN = 8'h11;

parameter STA_IDLE = 3'b001;
parameter STA_AMP = 3'b010;
parameter STA_ADC = 3'b100;

reg [2:0] Cur_State, Nxt_State;
reg [6:0] Cnter;
reg [13:0] Reg_ADC_CH1, Reg_ADC_CH2;
reg [7:0] Reg_AMP_Gain;

always @( posedge Clk )
begin
 if( Rst )
  Cur_State <= STA_IDLE;
 else
  Cur_State <= Nxt_State;
end


always @( Cur_State or Cnter )
begin
 case( Cur_State )
 STA_IDLE :
  begin
   if( Cnter == 7'd2 )
    Nxt_State = STA_AMP;
   else
    Nxt_State = STA_IDLE;
  end
 STA_AMP  :
  begin
   if( Cnter == 7'd16 )
    Nxt_State = STA_ADC;
   else
    Nxt_State = STA_AMP;
  end
 STA_ADC  :
  begin
   Nxt_State = STA_ADC;  
  end
 default  :
  begin
   Cur_State = STA_IDLE;
  end
 endcase 
end

always @( posedge Clk )
begin
 if( Rst )
 begin
  AMP_nCS <= 1'b1;
  SPI_MOSI <= 1'b0;
  SPI_SCK <= 1'b1;
  AD_CONV <= 1'b0;
  Reg_AMP_Gain <= 14'h0000;
  Reg_ADC_CH1 <= 14'h0000;
  Reg_ADC_CH2 <= 8'h00;
  Cnter <= 7'h00;
 end
 else
 begin
  case( Cur_State )
  STA_IDLE :
   begin
    if( Cnter < 7'd2 )
    begin
     AMP_nCS <= 1'b1;
     SPI_MOSI <= 1'b0;
     SPI_SCK <= 1'b1;
     AD_CONV <= 1'b0;
     Reg_AMP_Gain <= AMP_GAIN;
     Cnter <= Cnter + 1'b1;
    end
    else
    begin
     AMP_nCS <= 1'b0;
     SPI_MOSI <= 1'b0;
     SPI_SCK <= 1'b1;
     AD_CONV <= 1'b0;
     Reg_AMP_Gain <= AMP_GAIN;
     Cnter <= 7'h00;     
    end
   end
  STA_AMP  :
   begin
    AMP_nCS <= 1'b0;
    if( Cnter < 7'd16 )
    begin
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
     begin
      SPI_SCK <= 1'b0;
      SPI_MOSI <= Reg_AMP_Gain[7];
      Reg_AMP_Gain <= { Reg_AMP_Gain[6:0], 1'b0 };
     end
     else
     begin
      SPI_SCK <= 1'b1;
     end    
    end
    else
    begin
     Cnter <= 7'd0;
     SPI_SCK <= 1'b1;
     AMP_nCS <= 1'b1;
     AD_CONV <= 1'b0;
    end
   end
  STA_ADC  :
   begin 
    if( Cnter==7'd0 )
    begin
     SPI_SCK <= 1'b0;
     AD_CONV <= 1'b1;
     Cnter <= Cnter + 1'b1;
    end
    else if( Cnter==7'd1 )
    begin
     SPI_SCK <= 1'b1;
     Cnter <= Cnter + 1'b1;
    end
    else if( Cnter <7'd6 )
    begin
     AD_CONV <= 1'b0;
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
      SPI_SCK <= 1'b0;
     else
      SPI_SCK <= 1'b1;
    end
    else if( Cnter <7'd34 )
    begin
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
      SPI_SCK <= 1'b0;
     else
     begin
      SPI_SCK <= 1'b1;
      Reg_ADC_CH1 <= { Reg_ADC_CH1[12:0], SPI_MISO };
     end
    end
    else if( Cnter <7'd38 )
    begin
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
      SPI_SCK <= 1'b0;
     else
     begin
      SPI_SCK <= 1'b1;
     end
    end
    else if( Cnter <7'd66 )
    begin
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
      SPI_SCK <= 1'b0;
     else
     begin
      SPI_SCK <= 1'b1;
      Reg_ADC_CH2 <= { Reg_ADC_CH2[12:0], SPI_MISO };
     end
    end
    else if( Cnter <7'd68 )
    begin
     Cnter <= Cnter + 1'b1;
     if( Cnter[0] == 1'b0 )
      SPI_SCK <= 1'b0;
     else
      SPI_SCK <= 1'b1;
    end
    else
    begin
     Cnter <= 7'd0;
    end
   end
  default  :
   begin
    AMP_nCS <= 1'b1;
    SPI_MOSI <= 1'b0;
    SPI_SCK <= 1'b1;
    AD_CONV <= 1'b0;
    Reg_AMP_Gain <= 14'h0000;
    Reg_ADC_CH1 <= 14'h0000;
    Reg_ADC_CH2 <= 8'h00;
    Cnter <= 7'h00;
   end
  endcase  
 end
end

// -------------------------- For Simulation ---------------------------------------
initial
begin
 Nxt_State = 3'b001; 
end

endmodule





Testbench程序--------------------------------------------------------------------------------------------------------

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    19:53:26 04/01/2011
// Design Name:
// Module Name:   
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

module tb_LTC_ADC;
//module tb_ltc_adc;
reg Clk;
reg Rst;
wire AMP_nCS, AMP_SHDN, SPI_MOSI, SPI_SCK, AD_CONV;
reg SPI_MISO;

LTC_ADC  uut(
 .Clk( Clk ),
 .Rst( Rst ),
 .AMP_nCS( AMP_nCS ),
 .AMP_SHDN( AMP_SHDN ),
 .SPI_MOSI( SPI_MOSI ),
 .SPI_SCK( SPI_SCK ),
 .AD_CONV( AD_CONV ),
 .SPI_MISO( SPI_MISO )
);

always #250 Clk = ~Clk;


initial
begin
// Initialize Inputs
 Clk = 0;
 Rst = 0;
 SPI_MISO = 0;
 
 #2000;
 Rst = 1;
 #2000;
 Rst = 0;
 #2000;
 
 while(1)
 begin
  @( negedge SPI_SCK )
   SPI_MISO = 1;
  @( negedge SPI_SCK )
   SPI_MISO = 0;
  @( negedge SPI_SCK )
   SPI_MISO = 0;
 end
end

endmodule


do文件为
#
# Create work library
#
vlib work
#
# Compile sources
#
vlog  "tb_LTC_ADC.v"
vlog  "LTC_ADC.v"


#vsim -voptargs="+acc" -t 1ps -lib work.tb_LTC_ADC glbl
vsim -t 1ps -novopt work.tb_LTC_ADC
#


#add wave /tb_LTC_ADC/*
#add wave /tb_LTC_ADC/uut/*

do {wave.do}

# Set the window types
#
view wave
view structure
view signals
#
# Source the user do file
#

#
# Run simulation for this time
#
run 100us
#
# End
#


贴出来的程序我就不排版了,详细的Modelsim工程我已经上传了,可以下载

——回复可见内容——

解压后,用Modelsim打开工程,输入 do run.do 就可以了。

PS.  只为吸引你的程序逻辑上有些乱,我就不帮你检查了,不好意思了。你就参考我的吧。

另外,希望大家以后有什么问题,还是在论坛上大家一起讨论吧,一般不接受站内PM、Email、QQ等提出的问题。




关键词: Spartan     开发     程序     专帖     State     Cn    

高工
2011-04-13 22:45:25     打赏
2楼

你把“程序”两个字漏了,呵呵。
其实主要是我嫌麻烦,所以就自己写了一个。要知道,有些时候读程序比写程序还麻烦。

我觉得状态机不需要分得你那么细。把AMP和ADC的配置作为大状态,再用一个计数器做小状态就可以了,而且时序图总也表明了数字,所以用计数器是比较方便的。

我的程序中,复位之后,先配置AMP,然后就一直读取ADC了。

你先运行一下仿真文件,看看时序是不是你需要的。有问题再讨论

当然了,我也没写注释,所以也不好看。还是根据仿真时序来分析比较容易些


高工
2011-04-14 10:15:13     打赏
3楼

嗯。外围的你自己封装一下,然后下载看看吧。我现在有事要出去,今晚才能再上网


高工
2011-04-15 21:22:13     打赏
4楼

是否正确,用示波器或逻辑分析仪捕获一下不就知道时序是什么样的了嘛


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]