FPGA的AD芯片驱动

FPGA的AD芯片驱动

(2012-08-19 15:37:02)
标签:

fpga

ad芯片驱动

it

分类: FPGA学习笔记

//2012年8月18日

//AD芯片驱动//作者:泪与汗的缠绵
module adc_ctrl(
    clk,rst_n,
    adc_data,adc_cs_n,adc_clk,
    sys_cs_n,sys_rd_n,sys_rddata
   );
input clk;  //50MHz
input rst_n; //低电平复位信号

input adc_data;  //TLC549数据信号
output adc_cs_n; //TLC549片选信号,低电平有效
output adc_clk;  //TLC549时钟信号

input sys_cs_n; //总线读片选,低电平有效
input sys_rd_n;   //总线读使能信号,低电平有效
output[7:0] sys_rddata; //总线读取数据

//---------------------------------------------------
//定时计数逻辑
reg[5:0] cntus; //1us计数器

always @(posedge clk or negedge rst_n)
 if(!rst_n) cntus <= 6'd0;
 else if((cntus < 6'd49) && (cstate != IDLE)) cntus <= cntus+1'b1;
 else cntus <= 6'd0;

wire dchag_flag = (cntus == 6'd0); //ADC时钟下降沿标志位,高有效一个时钟周期
wire dlock_flag = (cntus == 6'd24); //ADC时钟上升沿标志位,高有效一个时钟周期

//---------------------------------------------------
//ADC工作状态机
parameter IDLE = 3'd0,
   TSUDL = 3'd1,
   START = 3'd2,
   DTRAN = 3'd3,
   STOP = 3'd4,
   TWHDL = 3'd5;

reg[2:0] bitnum; //采样数据位寄存器7-0
reg[4:0] d17uscnt; //Twh延时计数器
reg[7:0] adc_dinr; //模数转换数据寄存器
reg[7:0] adc_dinlock; //模数转换数据寄存器,实时锁存
reg[2:0] cstate,nstate; //状态寄存器
 
 //状态迁移
always @(posedge clk or negedge rst_n)
 if(!rst_n) cstate <= IDLE;
 else cstate <= nstate;

 //数据采集位寄存器控制
always @(posedge clk or negedge rst_n)
 if(!rst_n) bitnum <= 3'd0;
 else if(nstate == IDLE) bitnum <= 3'd7;  
 else if((nstate == DTRAN) && dlock_flag) bitnum <= bitnum-1'b1;

 //Twh延时计数器控制
always @(posedge clk or negedge rst_n)
 if(!rst_n) d17uscnt <= 5'd0;
 else if((nstate == TWHDL) && dchag_flag) d17uscnt <= d17uscnt+1'b1;
 else if(nstate == IDLE) d17uscnt <= 5'd0; 
 
 //状态控制
always @(cstate or dchag_flag or bitnum or d17uscnt)
 case(cstate)
  IDLE:  nstate <= TSUDL;
  TSUDL: if(dchag_flag) nstate <= START;
    else nstate <= TSUDL;
  START: if(dchag_flag) nstate <= DTRAN;
    else nstate <= START;
  DTRAN: if(dchag_flag && (bitnum == 3'd7)) nstate <= STOP;
    else nstate <= DTRAN;
  STOP: if(dchag_flag) nstate <= TWHDL;
    else nstate <= STOP;
  TWHDL: if(dchag_flag && (d17uscnt == 5'd18)) nstate <= IDLE;
    else nstate <= TWHDL;
  default: nstate <= IDLE;
  endcase

 //数据锁存
always @(posedge clk or negedge rst_n)
 if(!rst_n) adc_dinlock <= 8'h00;
 else if((nstate == DTRAN) && dlock_flag) adc_dinlock[bitnum] <= adc_data; //数据锁存

always @(posedge clk or negedge rst_n)
 if(!rst_n) adc_dinr <= 8'h00;
 else if((nstate == STOP) && sys_rdcs_n) adc_dinr <= adc_dinlock;

assign adc_cs_n = ~((cstate == DTRAN) | (cstate == START) | (cstate == TSUDL)); 

//---------------------------------------------------
//时钟速率控制,1MHz
reg adc_clkr; //TLC549时钟信号寄存器

always @(posedge clk or negedge rst_n)
 if(!rst_n) adc_clkr <= 1'b0;
 else if((nstate == DTRAN) && (cntus > 5'd12)) adc_clkr <= 1'b1;
 else adc_clkr <= 1'b0;

assign adc_clk = adc_clkr;

//---------------------------------------------------
//Avalon-MM接口逻辑
wire sys_rdcs_n = sys_cs_n | sys_rd_n;

reg sys_dlink; //数据输出控制,高电平有效

always @(posedge clk or negedge rst_n)
 if(!rst_n) sys_dlink <= 1'b1;
 else sys_dlink <= sys_rdcs_n; //锁存读片选译码

assign sys_rddata = sys_dlink ? 8'hzz:adc_dinr;

endmodule

 

转载于:https://www.cnblogs.com/xiaweiyu/archive/2013/06/01/3113215.html

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值