用FPGA驱动AD-TLC549芯片

 

介绍:

TLC549是 TI公司生产的一种低价位、高性能的8位 A/D转换器,采用了CMOS工艺,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于 17us,最大转换速率为 40Khz,4MHZ典型内部系统时钟,电源为 3V至 6V。采用三线串行接口方式与各种微处理器连接,构成各种廉价的测控应用系统。

工作原理

REF+:正基准电压输入 2.5V≤REF+≤Vcc+0.1。

REF-:负基准电压输入端,-0.1V≤REF-≤2.5V。且要求:(REF+)-(REF-)≥1V。

VCC:系统电源3V≤Vcc≤6V。

GND:接地端。

CS:芯片选择输入端,要求输入高电平 VIN≥2V,输入低电平 VIN≤0.8V。

DATA OUT:转换结果数据串行输出端,与 TTL 电平兼容,输出时高位在前,低位在后。

ANALOG IN:模拟信号输入端,0≤ANALOGIN≤Vcc,当 ANALOGIN≥REF+电压时,转换结果为全“1”(0FFH),ANALOGIN≤REF-电压时,转换结果为全“0”(00H)。

I/O CLOCK:外接输入/输出时钟输入端,同于同步芯片的输入输出操作,无需与芯片内部系统时钟同步

运用:

        时序图:

根据工作时序所示。

  当CS为高时,数据输出(DATA OUT)端处于高阻状态,此时I/O CLOCK不起作用。

  当CS为低时,AD前一次转换的数据A的最高位A7立马出现在数据线DATA OUT上,其余七位在I/O CLOCK的下降沿依次由时钟同步输出,,所以可在I/O CLOCK的上升沿读取数据,从第8个 I/O CLOCK 信号的下降沿使片内采样/保持电路进入保持状态并启动 A/D开始转换。片选信号CS置高,每次转换不超过17us,开始于CS拉低后的第八个I/O CLOCK的下降沿,没有转换完成标志,没有启动控制端,只要读取前一次数据后就马上可以开始新的AD转换,转换完成进入保持状态。其中需要注意的是:tsu(cs)至少要1.4us;2.I/O CLOCK不能超过1.1MHz。

        接线图:

实验目的:可以用FPGA得到TLC549输出的数据

模块框图:

状态图:

模块代码

module ad1549(

    input wire data_dat,
    input wire rst,
    input wire clk,
    
    output reg dat_clk,
    output reg cs, 
    output reg flag_data,
    output reg [7:0]data_out

    );
 
parameter IDLE = 3'b001,
           ONE  = 3'b010,
           TUW  = 3'b100; 

parameter sum_7_max =3'd7;
parameter sum_1mh_max =10'd999;
parameter sum_cs_max =11'd1_999;
parameter sum_20us_max =15'd1_999_9;
parameter sum_cs_f_max =16'd4_999_9; 

reg data_dat1;
reg data_dat2;

reg [0:2] state;

reg sum_cs_flag;

reg [0:9]sum_1mh;
reg [0:2]sum_7;
reg [0:10]sum_cs;
reg [0:14]sum_20us;
reg [0:15]sum_cs_f;

reg [7:0]data_out_s;

//对其数据
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    data_dat1 <= 1'd0;
else 
    data_dat1 <= data_dat;
end 

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    data_dat2 <= 1'd0;
else 
    data_dat2 <= data_dat;
end 

//计数器模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_20us <= 15'd0;
else if( sum_20us== sum_20us_max)
    sum_20us <= 15'd0;
else if(sum_cs_flag==1'b0)
    sum_20us <= sum_20us+15'd1;
end 

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_1mh <= 10'd0;
else if( sum_1mh== sum_1mh_max)
    sum_1mh <= 10'd0;
else
    sum_1mh <= sum_1mh+10'd1;
end 

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_cs_f <= 16'd0;
else if( sum_cs_f== sum_cs_f_max)
    sum_cs_f <= 16'd0;
else
    sum_cs_f <= sum_cs_f+16'd1;
end



//flag模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_cs_flag <= 1'd0;
else if((sum_cs== 11'b0)&&(cs == 1'd0))
    sum_cs_flag <= 1'd1;
else
    sum_cs_flag <= 1'd0;    
end 

//dat_clk:clk_out模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    dat_clk <= 1'b0;
else if( sum_1mh== sum_1mh_max)
    dat_clk <= ~dat_clk;
else
    dat_clk <= dat_clk;
end 

//sum_7模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_7 <= 3'd0;
else if(sum_cs_flag == 1'd0)
    sum_7 <= 3'd0;
else if((sum_1mh== sum_1mh_max)&&(sum_cs_flag == 1'd1))
    sum_7 <= sum_7+3'd1;
else 
    sum_7 <= sum_7;    
end 

//cs信号模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    cs <= 1'd1;
else if(sum_cs_f== sum_cs_f_max)
    cs <= ~cs;
else 
    cs <= cs;   
end 

//读取信号模块
always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    data_out_s <= 8'd0;
else if((sum_7<=sum_7_max)&&(sum_1mh== sum_1mh_max))
    data_out_s <= {data_dat2,data_out_s[7:1]};
else
    data_out_s <=data_out_s;
end 

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    data_out <= 8'd0;
else if(sum_7==sum_7_max)
    data_out <= data_out_s;
else
    data_out <=data_out;
end 


always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    state <= IDLE;
else 
    case (state)
        IDLE: if((cs==1'b0)&&(sum_cs==sum_cs_max)) state <= ONE;
        ONE:  if((cs==1'b0)&&(sum_7 ==sum_7_max)) state <=TUW;
        TUW:  if((cs==1'b1)&&(sum_20us== sum_20us_max)) state <=IDLE;
        default : state <= IDLE;
    endcase 
end    

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    flag_data <= 1'd0;
else if(state==ONE)
    flag_data <= 1'd1;
else
    flag_data <= 1'd0;    
end 

always@(posedge clk or negedge rst)   
begin 
if(rst==1'b0)
    sum_cs <= 11'd0;
else if( state!= IDLE)
    sum_cs <= 11'd0;
else if( sum_cs== sum_cs_max )
    sum_cs <= sum_cs;    
else if( state == IDLE)
    sum_cs <= sum_cs+11'd1;
end 


endmodule

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值