已回答假定已回答

关于AD5242使用问题

YukiPan 在 2018-4-20 詢問的問題

想请教一下,为何我用FPGA控制AD5242写的时候,两个电位器之间阻值变化会相互影响?就是同一个芯片中0号变化以后,去变化1号,反过来看0号,它也变了。我用同一根IIC控制4个此芯片,这4个芯片间也会有相互影响。

以下是我的FPGA程序,请大神指点~

 

module write(

  clk,rst_n,

  sda,scl,data_24,iic_en

  );

 

 

input clk; // 50MHz

input rst_n;

input [23:0] data_24;

inout sda;

output scl;

input iic_en;   //effective on 1

 

 

 

 

 

 

//---------------------------------------------

reg[2:0] cnt;

reg[9:0] cnt_delay;

reg scl_r;

 

 

always @ (posedge clk or negedge rst_n)

if(!rst_n) cnt_delay <= 9'd0;
else if(cnt_delay == 9'd499) cnt_delay <= 9'd0;
else cnt_delay <= cnt_delay+1'b1;

 

 

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) cnt <= 3'd5;
else begin
case (cnt_delay)
9'd124:cnt <= 3'd1;
9'd249:cnt <= 3'd2;
9'd280:cnt <= 3'd3;
9'd499:cnt <= 3'd0;
default: cnt <= 3'd5;
endcase
end

end

 

 

 

 

always @ (posedge clk or negedge rst_n)

if(!rst_n) scl_r <= 1'b1;
else if(cnt==3'd0) scl_r <= 1'b1;
   else if(cnt==3'd2) scl_r <= 1'b0;

 

 

assign scl = scl_r;

 

 

`define SCL_POS (cnt_delay==9'd499)

`define SCL_HIG (cnt_delay==9'd124)

`define SCL_NEG (cnt_delay==9'd249)

`define SCL_LOW (cnt_delay==9'd280)

 

 

//---------------------------------------------

reg[3:0] num;

reg[7:0] db_r;

reg sda_link;

reg[7:0] sda_r;

reg[3:0] cstate;

 

parameter START = 4'd0;

parameter ADD1 = 4'd1;

parameter ACK1 = 4'd2;

parameter ADD2 = 4'd3;

parameter ACK2 = 4'd4;

parameter DATA = 4'd5;

parameter ACK3 = 4'd6;

parameter STOP1 = 4'd7;

parameter ENABLE = 4'd8;

 

 

//---------------------------------------------

always @ (posedge clk or negedge rst_n) begin

  if(!rst_n) begin

       num <= 3'd0;

  sda_link <= 1'b1;

  sda_r <= 1'b1;

    cstate <= ENABLE;

  end

 

 

  else begin             

      case (cstate)

  ENABLE:begin

  if(iic_en)

begin

  cstate <= START;

  end

  else cstate <= ENABLE;

  end

 

  START: begin

  if(`SCL_HIG) begin

  sda_link <= 1'b1;

  db_r <= data_24[23:16];

  sda_r <= 1'b0;

  cstate <= ADD1;

  num <= 4'd0;

  end

  else cstate <= START;

  end

 

  ADD1: begin

  if(`SCL_LOW) begin

  if(num == 4'd8) begin

  num <= 4'd0;

  sda_r <= 1'b1;

  sda_link <= 1'b0;

  cstate <= ACK1;

  end

  else begin

  cstate <= ADD1;

  num <= num+1'b1;

  case (num)

  4'd0: sda_r <= db_r[7];

  4'd1: sda_r <= db_r[6];

  4'd2: sda_r <= db_r[5];

  4'd3: sda_r <= db_r[4];

  4'd4: sda_r <= db_r[3];

  4'd5: sda_r <= db_r[2];

  4'd6: sda_r <= db_r[1];

  4'd7: sda_r <= db_r[0];

    default: ;

  endcase

   end

  end

                else cstate <= ADD1;

      end 

 

         ACK1: begin

  if(/*!sda*/`SCL_NEG) begin

  cstate <= ADD2;

  db_r <= data_24[15:8];

   

  end 

  else cstate <= ACK1;

  end

 

   ADD2: begin

  if(`SCL_LOW) begin

  if(num == 4'd8) begin

  sda_link <= 1'b0;

  sda_r <= 1'b1;

  num <= 4'd0;

  cstate <= ACK2;

  end

  else begin

  sda_link <= 1'b1;

  cstate <= ADD2;

  num <= num+1'b1;

  case (num)

  4'd0: sda_r <= db_r[7];

  4'd1: sda_r <= db_r[6];

  4'd2: sda_r <= db_r[5];

  4'd3: sda_r <= db_r[4];

  4'd4: sda_r <= db_r[3];

  4'd5: sda_r <= db_r[2];

  4'd6: sda_r <= db_r[1];

  4'd7: sda_r <= db_r[0];

    default: ;

  endcase

                        end

  end

                else cstate <= ADD2;

      end

 

         ACK2: begin

  if(/*!sda*/`SCL_NEG) begin

  cstate <= DATA;

  db_r <= data_24[7:0];

 

  end

  else cstate <= ACK2;

  end

 

DATA: begin

  if(`SCL_LOW) begin

  if(num == 4'd8) begin

  sda_link <= 1'b0;

  sda_r <= 1'b1;

  num <= 4'd0;

  cstate <= ACK3;

  end

  else begin

  sda_link <= 1'b1;

  cstate <= DATA;

  num <= num+1'b1;

  case (num)

   4'd0: sda_r <= db_r[7];

  4'd1: sda_r <= db_r[6];

  4'd2: sda_r <= db_r[5];

  4'd3: sda_r <= db_r[4];

  4'd4: sda_r <= db_r[3];

  4'd5: sda_r <= db_r[2];

  4'd6: sda_r <= db_r[1];

  4'd7: sda_r <= db_r[0];

    default: ;

  endcase

                        end

  end

                else cstate <= DATA;

      end

 

ACK3: begin

  if(/*!sda*/`SCL_NEG) begin

  sda_r <= 1'b0;

  sda_link <= 1'b1;

  cstate <= STOP1;

  end

  else cstate <= ACK3;

  end

  STOP1: begin

  if(`SCL_HIG) begin

  sda_link <= 1'b1;

  sda_r <= 1'b1;

  cstate <= START;

  end

  else cstate <= STOP1;

  end

 

  default: cstate <= START;

  endcase

  end

end

assign sda = sda_link ? sda_r:1'bz;

//---------------------------------------------

 

 

endmodule

結果