首页 > 代码库 > ADS7830 FPGA实现

ADS7830 FPGA实现

 
PCB设计的一般原则
 
Xilinx学习心得1-管脚约束

ADS7830 FPGA实现  

2012-05-11 11:18:12|  分类: 工作笔记 |  标签: |字号 订阅

 
 

ADS7830是TI的一款8bit,8channel AD转换芯片,对应通过I2c接口进行配置和读;以下是我用verilog编写的程序,已经验证过了,完全ok,输入的时钟是125MHz。经过分频成200Khz,采用的I2c接口时钟是100Khz模式;这里为了给上层模块应用,将inout类型的Sda在上层模块处理了;

module I2c_ADS7830 #(parameter DIV_PARA = 625)(  input clk,  input rst_n,  input AD_req,  input[2:0] AD_channel,    output reg dout_valid,  output reg [7:0] dout,   // output reg flag0,    output reg scl,  input sda_in,  output reg sda_out,  output reg en  ); localparam HARD_ADDR = 8‘b1001_0000;   localparam I2C_IDLE = 4‘d0,I2C_START = 4‘d1,I2C_HADDR = 4‘d2,I2C_HADDR_ACK = 4‘d3,     I2C_CMD = 4‘d4,I2C_CMD_ACK = 4‘d5,I2C_RESTART = 4‘d6,I2C_WRADDR = 4‘d7,     I2C_WRADDR_ACK = 4‘d8,I2C_RDATA = http://www.mamicode.com/4‘d9,I2C_NACK = 4‘d10,I2C_STOP = 4‘d11;

reg[3:0] current_state;  reg[2:0] AD_channel_buf; reg[7:0] databuf; reg[7:0] doutbuf;

reg i2c_clk; reg[9:0] div_cnt; reg[3:0] i2c_cnt;

reg start_AD; reg ack_AD; reg finish_AD; reg finish_AD_reg0,finish_AD_reg1;

//always@(posedge clk or negedge rst_n) //if(~rst_n) // flag0 <= 1‘b0; //else if(finish_AD) // flag0 <= 1‘b1;   //reg en; //reg sda_reg; // //assign sda  = en ? sda_reg : 1‘bz;

always@(posedge clk or negedge rst_n) if(~rst_n)  i2c_clk <= 1‘b0; else if(div_cnt==DIV_PARA-1)  i2c_clk <= ~i2c_clk;

always@(posedge clk or negedge rst_n) if(~rst_n)  div_cnt <= 10‘d0; else if(div_cnt==DIV_PARA-1)  div_cnt <= 10‘d0; else  div_cnt <= div_cnt + 10‘d1;

always@(posedge clk or negedge rst_n) if(~rst_n)  AD_channel_buf <= 3‘d0; else if(AD_req)  AD_channel_buf <= AD_channel;

always@(posedge clk or negedge rst_n) if(~rst_n)  start_AD <= 1‘b0; else if(AD_req)  start_AD <= 1‘b1; else if(ack_AD)  start_AD <= 1‘b0;

always@(posedge clk or negedge rst_n) if(~rst_n)  begin  finish_AD_reg0 <= 1‘b0;  finish_AD_reg1 <= 1‘b0;  end else  begin  finish_AD_reg0 <= finish_AD;  finish_AD_reg1 <= finish_AD_reg0;  end

always@(posedge clk or negedge rst_n) if(~rst_n)  dout_valid <= 1‘b0; else if(finish_AD_reg0 & !finish_AD_reg1)  dout_valid <= 1‘b1; else  dout_valid <= 1‘b0;

always@(posedge clk or negedge rst_n) if(~rst_n)  dout <= 8‘d0; else if(dout_valid)  dout <= doutbuf;

always@(posedge i2c_clk or negedge rst_n) if(~rst_n)  ack_AD <= 1‘b0; else if(start_AD)  ack_AD <= 1‘b1; else  ack_AD <= 1‘b0;   always@(posedge i2c_clk or negedge rst_n) if(~rst_n)  finish_AD <= 1‘b0; else if(current_state == I2C_STOP)  finish_AD <= 1‘b1; else  finish_AD <= 1‘b0;   always@(posedge i2c_clk or negedge rst_n) if(~rst_n)  i2c_cnt <= 4‘d0; else
 case(current_state)  I2C_HADDR,I2C_CMD,  I2C_WRADDR,I2C_RDATA:   begin   if(i2c_cnt==4‘d15)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  I2C_START,I2C_HADDR_ACK,I2C_CMD_ACK,  I2C_WRADDR_ACK,I2C_NACK,I2C_STOP:   begin   if(i2c_cnt==4‘d1)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  I2C_RESTART:   begin   if(i2c_cnt==4‘d2)    i2c_cnt <= 4‘d0;   else    i2c_cnt <= i2c_cnt + 4‘d1;   end  default:i2c_cnt <= 4‘d0;  endcase

always@(posedge i2c_clk or negedge rst_n) if(~rst_n)  current_state <= I2C_IDLE; else  case(current_state)  I2C_IDLE:   begin   if(start_AD)    current_state <= I2C_START;   end  I2C_START:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_HADDR;   end  I2C_HADDR:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_HADDR_ACK;   end  I2C_HADDR_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_CMD;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //      current_state <= I2C_CMD;   end  I2C_CMD:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_CMD_ACK;   end  I2C_CMD_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_RESTART;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //     current_state <= I2C_RESTART;   end  I2C_RESTART:   begin   if(i2c_cnt==4‘d2)    current_state <= I2C_WRADDR;   end  I2C_WRADDR:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_WRADDR_ACK;   end  I2C_WRADDR_ACK:   begin   if(scl && !sda_in)    current_state <= I2C_RDATA;   else if(scl && sda_in)    current_state <= I2C_IDLE; //   if(scl) //     current_state <= I2C_RDATA;   end  I2C_RDATA:   begin   if(i2c_cnt==4‘d15)    current_state <= I2C_NACK;   end  I2C_NACK:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_STOP;   end  I2C_STOP:   begin   if(i2c_cnt==4‘d1)    current_state <= I2C_IDLE;   end  default:current_state <= I2C_IDLE;  endcase     always@(posedge i2c_clk or negedge rst_n) if(~rst_n)  begin  scl <= 1‘b0;  en <= 1‘b0;  sda_out <= 1‘b0;  databuf <= 8‘d0;  doutbuf <= 8‘d0;  end else  case(current_state)  I2C_IDLE:   begin   scl <= 1‘b1;   sda_out <= 1‘b1;   en <= 1‘b1;   end  I2C_START:   begin   if(i2c_cnt==4‘d0)     begin     scl <= 1‘b1;     sda_out <= 1‘b0;     end   else     scl <= 1‘b0;   databuf <= HARD_ADDR;   end  I2C_HADDR:   begin   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_HADDR_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   databuf <= {1‘b1,AD_channel_buf,4‘b0100};   end  I2C_CMD:   begin   en <= 1‘b1;   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_CMD_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   databuf <= HARD_ADDR + 1‘b1;   end  I2C_RESTART:   begin   en <= 1‘b1;   if(i2c_cnt==4‘d0)    begin    scl <= 1‘b1;    sda_out <= 1‘b1;    end   else if(i2c_cnt==4‘d1)    begin    sda_out <= 1‘b0;    scl <= 1‘b1;    end   else    scl <= 1‘b0;   databuf <= HARD_ADDR + 1‘b1;   end  I2C_WRADDR:   begin   scl <= ~scl;   if(!scl)    begin    sda_out <= databuf[7];    databuf <= {databuf[6:0],1‘b0};    end   end  I2C_WRADDR_ACK:   begin   en <= 1‘b0;   scl <= ~scl;   end  I2C_RDATA:   begin   en <= 1‘b0;   scl <= ~scl;   if(!scl)    doutbuf <= {doutbuf[6:0],sda_in};   end  I2C_NACK:   begin   en <= 1‘b0;   scl <= ~scl;   end  I2C_STOP:   begin   en <= 1‘b1;   scl <= 1‘b1;   if(i2c_cnt==4‘d0)    sda_out <= 1‘b0;   else    sda_out <= 1‘b1;   end  default:;  endcase

endmodule

ADS7830 FPGA实现