OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 企业专区 » Xilinx » Spartan 3E开发板上的ADC程序专帖

共23条 1/3 1 2 3 跳转至

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 21:50:29    评分
2楼
呃,我的逻辑有些乱·········

高工
2011-04-13 22:45:25    评分
3楼

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

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

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

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

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


菜鸟
2011-04-14 09:06:22    评分
4楼
昨天晚上看了,也仿真了,总的来看挺清楚的,就是sck那看得我那叫一个乱,呵呵。今天烧板子试一试,谢谢了。

工程师
2011-04-14 09:54:47    评分
5楼
很好,学习了

高工
2011-04-14 10:15:13    评分
6楼

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


菜鸟
2011-04-14 22:21:31    评分
7楼
我烧了你的程序,频率太高,有20几M。那个amp最大就能到10M。我给加了个分频。分到了8.+M。烧上还是不行,amp 放大输出,总是一个高电平。可能是那个放大的增益时序那,没弄好。觉得那个sck太繁琐了。我就还是改的我的那个程序。当然也是很繁琐,不过好在现在看见曙光了。呵呵

专家
2011-04-15 08:33:53    评分
8楼
楼主是好人娜,鼓励一下!!

菜鸟
2011-04-15 10:22:57    评分
9楼

好啊,我也在弄Spartan 3EXCS500E,支持一下啊


菜鸟
2011-04-15 21:09:44    评分
10楼
共同学习啊,

共23条 1/3 1 2 3 跳转至

回复

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