verilog怎么控制iic的读写,怎么控制多个数据的。。求大神
答案:2 悬赏:40 手机版
解决时间 2021-01-23 07:07
- 提问者网友:心牵心
- 2021-01-22 17:33
verilog怎么控制iic的读写,怎么控制多个数据的。。求大神
最佳答案
- 五星知识达人网友:痴妹与他
- 2021-01-22 19:02
什么是单个数据?IIC总线就是把所需的数据经sda数据线串行传入芯片中,需要多少传多少就是 了,我这有个以前写的IIC控制WM8731的例程,你可以参考下
//`timescale 1ns / 1ps
module i2c_control(
clk,
i2c_sclk,
i2c_sdat,
i2c_data,
start,
tr_end,
ack,
rst,
counter,
sdo);
input clk;
input [23:0]i2c_data;
input start;
input rst;
// input w_r;
inout i2c_sdat;
output i2c_sclk;
output tr_end;
output ack;
output [5:0]counter;
output sdo;
reg sdo;
reg sclk;
reg tr_end;
reg [23:0]sd;
reg [5:0]counter;
assign i2c_sclk=sclk |(((counter>=4)&(counter<=30))?~clk:0);
assign i2c_sdat=sdo?1'bz:0;
reg ack1,ack2,ack3;
wire ack=ack1 |ack2 |ack3;
always@(negedge rst or posedge clk)begin
if(!rst)counter<=6'b111111;
else begin
if(start==0)
counter<=0;
else
if(counter<6'b111111)counter<=counter+1;
end
end
always@(negedge rst or posedge clk)begin
if(!rst)begin sclk<=1;sdo<=1;ack1<=0;ack2<=0;ack3<=0;tr_end<=0;end
else
case(counter)
6'd0 :begin ack1<=0;ack2<=0;ack3<=0;tr_end<=0;sdo<=1;sclk<=1;end
6'd1 :begin sd<=i2c_data;sdo<=0;end
6'd2 :sclk=0;
6'd3 :sdo<=sd[23];
6'd4 :sdo<=sd[22];
6'd5 :sdo<=sd[21];
6'd6 :sdo<=sd[20];
6'd7 :sdo<=sd[19];
6'd8 :sdo<=sd[18];
6'd9 :sdo<=sd[17];
6'd10 :sdo<=sd[16];
6'd11 :sdo<=1'b1;
6'd12 :begin sdo<=sd[15];ack1<=i2c_sdat;end
6'd13 :sdo<=sd[14];
6'd14 :sdo<=sd[13];
6'd15 :sdo<=sd[12];
6'd16 :sdo<=sd[11];
6'd17 :sdo<=sd[10];
6'd18 :sdo<=sd[9];
6'd19 :sdo<=sd[8];
6'd20 :sdo<=1'b1;
6'd21 :begin sdo<=sd[7];ack2<=i2c_sdat;end
6'd22 :sdo<=sd[6];
6'd23 :sdo<=sd[5];
6'd24 :sdo<=sd[4];
6'd25 :sdo<=sd[3];
6'd26 :sdo<=sd[2];
6'd27 :sdo<=sd[1];
6'd28 :sdo<=sd[0];
6'd29 :sdo<=1'b1;
6'd30 :begin sdo<=1'b0;sclk<=1'b0;ack3<=i2c_sdat;end
6'd31 :sclk<=1'b1;
6'd32 :begin sdo<=1'b1;tr_end<=1;end
endcase
end
endmodule
//`timescale 1ns / 1ps
module i2c_control(
clk,
i2c_sclk,
i2c_sdat,
i2c_data,
start,
tr_end,
ack,
rst,
counter,
sdo);
input clk;
input [23:0]i2c_data;
input start;
input rst;
// input w_r;
inout i2c_sdat;
output i2c_sclk;
output tr_end;
output ack;
output [5:0]counter;
output sdo;
reg sdo;
reg sclk;
reg tr_end;
reg [23:0]sd;
reg [5:0]counter;
assign i2c_sclk=sclk |(((counter>=4)&(counter<=30))?~clk:0);
assign i2c_sdat=sdo?1'bz:0;
reg ack1,ack2,ack3;
wire ack=ack1 |ack2 |ack3;
always@(negedge rst or posedge clk)begin
if(!rst)counter<=6'b111111;
else begin
if(start==0)
counter<=0;
else
if(counter<6'b111111)counter<=counter+1;
end
end
always@(negedge rst or posedge clk)begin
if(!rst)begin sclk<=1;sdo<=1;ack1<=0;ack2<=0;ack3<=0;tr_end<=0;end
else
case(counter)
6'd0 :begin ack1<=0;ack2<=0;ack3<=0;tr_end<=0;sdo<=1;sclk<=1;end
6'd1 :begin sd<=i2c_data;sdo<=0;end
6'd2 :sclk=0;
6'd3 :sdo<=sd[23];
6'd4 :sdo<=sd[22];
6'd5 :sdo<=sd[21];
6'd6 :sdo<=sd[20];
6'd7 :sdo<=sd[19];
6'd8 :sdo<=sd[18];
6'd9 :sdo<=sd[17];
6'd10 :sdo<=sd[16];
6'd11 :sdo<=1'b1;
6'd12 :begin sdo<=sd[15];ack1<=i2c_sdat;end
6'd13 :sdo<=sd[14];
6'd14 :sdo<=sd[13];
6'd15 :sdo<=sd[12];
6'd16 :sdo<=sd[11];
6'd17 :sdo<=sd[10];
6'd18 :sdo<=sd[9];
6'd19 :sdo<=sd[8];
6'd20 :sdo<=1'b1;
6'd21 :begin sdo<=sd[7];ack2<=i2c_sdat;end
6'd22 :sdo<=sd[6];
6'd23 :sdo<=sd[5];
6'd24 :sdo<=sd[4];
6'd25 :sdo<=sd[3];
6'd26 :sdo<=sd[2];
6'd27 :sdo<=sd[1];
6'd28 :sdo<=sd[0];
6'd29 :sdo<=1'b1;
6'd30 :begin sdo<=1'b0;sclk<=1'b0;ack3<=i2c_sdat;end
6'd31 :sclk<=1'b1;
6'd32 :begin sdo<=1'b1;tr_end<=1;end
endcase
end
endmodule
全部回答
- 1楼网友:由着我着迷
- 2021-01-22 20:05
IIC都是两根线,只不过这两根线可能跟很多芯片的管脚复用。那么多芯片怎么办?加地址线当片选信号吧!
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯