MPU6050初始化时下发MPU6050地址11010000,可以读到响应位,但是紧接着下发寄存器地址时无响应这个是什么情况,求各位大神帮忙看看,
module test(CLK,RSTn,SDA,SCL);
input CLK;
input RSTn;
output SCL;
inout SDA;
reg[1:0] I2C_EN;
reg[7:0] I2C_iADDR;
reg[7:0] I2C_iDATA;
wire[7:0] I2C_oDATA;
wire I2C_DONE;
reg[4:0] cnt;
reg [7:0] reg_fifo[99:0];
reg [9:0] fifo_cnt_read;
reg [9:0] fifo_cnt_write;
parameter SMPLRT_DIV=8'd25;
parameter CONFIG=8'd26;
parameter GYRO_CONFIG=8'd27;
parameter ACCEL_CONFIG=8'd28;
parameter PWR_MGMT_1=8'h6B;
parameter WHO_AM_I=8'd117;
parameter ACCEL_XOUT_H=8'd59; //存储X轴加速度计最近的测量数据,16位ADC
parameter ACCEL_XOUT_L=8'd60;
parameter ACCEL_YOUT_H=8'd61; //存储Y轴加速度计最近的测量数据,16位ADC
parameter ACCEL_YOUT_L=8'd92;
parameter ACCEL_ZOUT_H=8'd63; //存储Z轴加速度计最近的测量数据,16位ADC
parameter ACCEL_ZOUT_L=8'd64;
parameter TEMP_OUT_H=8'd65; //存储温度传感器最近的测量值
parameter TEMP_OUT_L=8'd66;
parameter GYRO_XOUT_H=8'd67; //存储X轴陀螺仪最近的测量值
parameter GYRO_XOUT_L=8'd68;
parameter GYRO_YOUT_H=8'd69; //存储Y轴陀螺仪最近的测量值
parameter GYRO_YOUT_L=8'd70;
parameter GYRO_ZOUT_H=8'd71; //存储Z轴陀螺仪最近的测量值
parameter GYRO_ZOUT_L=8'd72;
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
cnt<=5'b0;
fifo_cnt_read<=10'b0;
I2C_iADDR<=8'b0;
I2C_iDATA<=8'b0;
reg_fifo[0]<=8'b0;
reg_fifo[1]<=8'b0;
reg_fifo[2]<=8'b0;
reg_fifo[3]<=8'b0;
I2C_EN<=2'b00;
end
else
begin
case(cnt)
0:
begin
I2C_EN<=2'b10;
I2C_iADDR<=PWR_MGMT_1; //PWR_MGMT_1
I2C_iDATA<=8'h00;
if(I2C_DONE)
cnt<=cnt+1'b1;
end
1:
begin
I2C_iADDR<=SMPLRT_DIV;
I2C_iDATA<=8'h07;
if(I2C_DONE)
cnt<=cnt+1'b1;
end
2:
begin
I2C_iADDR<=CONFIG;
I2C_iDATA<=8'h06;
if(I2C_DONE)
cnt<=cnt+1'b1;
end
3:
begin
I2C_iADDR<=GYRO_CONFIG;
I2C_iDATA<=8'h18;
if(I2C_DONE)
cnt<=cnt+1'b1;
end
4:
begin
I2C_iADDR<=ACCEL_CONFIG;
I2C_iDATA<=8'h01;
if(I2C_DONE)
begin
cnt<=cnt+1'b1;
end
end
5:
begin
I2C_EN<=2'b01;
I2C_iADDR<=ACCEL_XOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
6:
begin
I2C_iADDR<=ACCEL_XOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
7:
begin
I2C_iADDR<=ACCEL_YOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
8:
begin
I2C_iADDR<=ACCEL_YOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
9:
begin
I2C_iADDR<=ACCEL_ZOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
10:
begin
I2C_iADDR<=ACCEL_ZOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
11:
begin
I2C_iADDR<=GYRO_XOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
12:
begin
I2C_iADDR<=GYRO_XOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
13:
begin
I2C_iADDR<=GYRO_YOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
14:
begin
I2C_iADDR<=GYRO_YOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
15:
begin
I2C_iADDR<=GYRO_ZOUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
16:
begin
I2C_iADDR<=GYRO_ZOUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
17:
begin
I2C_iADDR<=TEMP_OUT_L;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=cnt+1'b1;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
18:
begin
I2C_iADDR<=TEMP_OUT_H;
if(I2C_DONE)
begin
reg_fifo[fifo_cnt_read]<=I2C_oDATA;
cnt<=5'd5;
fifo_cnt_read<=fifo_cnt_read+1'b1;
end
else if(fifo_cnt_read==10'd99)
fifo_cnt_read<=10'd0;
end
endcase
end
IIC I2C(
.CLK(CLK),
.RSTn(RSTn),
.SDA(SDA),
.iCALL(I2C_EN),
.iADDR(I2C_iADDR),
.iDATA(I2C_iDATA),
.SCL(SCL),
.oDONE(I2C_DONE),
.oDATA(I2C_oDATA)
);
endmodule
module IIC(
input CLK,
input RSTn,
inout SDA,
input [1:0] iCALL,
input [7:0] iADDR,
input [7:0] iDATA,
output SCL,
output oDONE,
output[7:0] oDATA
);
reg[4:0] i;
reg[4:0] GO;
reg[7:0] C1;
reg[7:0] D1;
reg rSCL;
reg rSDA;
reg isACK;
reg isDONE;
reg isQ;
parameter FCLK=125,FHALF=62,FQUARTER=31,THIGH=30,TLOW=65;
parameter TR=15,TF=15,THD_STA=30,TSU_STA=30,TSU_STO=30;
parameter FF_WRITE1=7,FF_WRITE2=9,RDFUNC=19;
always@(posedge CLK or negedge RSTn)
if(!RSTn)
begin
i<=5'b0;
GO<=5'b0;
C1<=8'b0;
D1<=8'b0;
rSCL<=1'b0;
rSDA<=1'b0;
isACK<=1'b0;
isDONE<=1'b0;
isQ<=1'b0;
end
else if(iCALL[1]) //使能写操作
begin
case(i)
0: //产生起始位
begin
isQ=1;
rSCL<=1'b1;
if(C1==8'b0)
rSDA<=1'b1;
else if(C1==(TR+THIGH))
rSDA<=1'b0;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
1: //输入设备地址
begin
D1<=8'b1101_0000;
i<=5'd7;
GO<=i+1'b1;
end
2: //输入数据地址
begin
D1<=iADDR;
i<=FF_WRITE1;
GO<=i+1'b1;
end
3: //输入数据
begin
D1<=iDATA;
i<=FF_WRITE1;
GO<=i+1'b1;
end
4: //结束位
begin
isQ=1;
if(C1==0)
begin
rSCL<=1'b0;
rSDA<=1'b0;
end
if(C1==FQUARTER)
rSCL<=1'b1;
if(C1==FHALF)
rSDA<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
5:
begin
isDONE<=1'b1;
i<=i+1'b1;
end
6:
begin
isDONE<=1'b0;
i<=5'b0;
end
7,8,9,10,11,12,13,14: //按位下发设备地址,数据地址,数据
begin
isQ=1;
rSDA<=D1[14-i];
if(C1==0)
rSCL<=1'b0;
if(C1==(TF+TLOW))
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
begin
C1<=C1+1'b1;
end
end
15: //读取应答位
begin
isQ=1'b0;
if(C1==FHALF)
isACK<=SDA;
if(C1==0)
rSCL<=1'b0;
else if(C1==FHALF)
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1;
end
else
C1<=C1+1'b1;
end
16: //判断从设备应答
begin
if(isACK!=0)
i<=5'b0;
else
i<=GO;
end
endcase
end
else if(iCALL[0]) //使能读操作
begin
case(i)
0: //产生起始位
begin
isQ=1;
if(C1==8'b0)
begin
rSDA<=1'b1;
rSCL<=1'b1;
end
else if(C1==(TR+THIGH))
rSDA<=1'b0;
else if(C1==(FHALF+FQUARTER))
rSCL<=1'b0;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
GO<=GO+1'b1;
end
else
C1<=C1+1'b1;
end
1: //输入设备地址
begin
D1<=8'b1101_0000;
i<=i+1'b1;
end
2,3,4,5,6,7,8,9: //按位下发设备地址,数据地址
begin
isQ=1;
rSDA<=D1[9-i];
if(C1==0)
rSCL<=1'b0;
if(C1==(TF+TLOW))
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
10: //读取应答位
begin
isQ=0;
if(C1==FHALF)
isACK<=SDA;
if(C1==0)
rSCL<=1'b0;
if(C1==FHALF)
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
11: //判断应答位
begin
if(isACK!=0)
begin
i<=5'b0;
GO<=5'b0;
end
else
begin
i<=i+GO;
GO<=GO+1'b1;
end
end
12: //输入数据地址
begin
D1<=iADDR;
i<=5'd2;
end
13: //读操作的二次起始位
begin
isQ=1;
if(C1==8'b0)
rSCL<=1'b0;
else if(C1==FQUARTER)
rSCL<=1'b1;
else if(C1==(FQUARTER+TR+TSU_STA+THD_STA+TF))
rSCL<=1'b0;
if(C1==8'b0)
rSDA<=1'b0;
else if(C1==FQUARTER)
rSDA<=1'b1;
else if(C1==(FQUARTER+TR+THIGH))
rSDA<=1'b0;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
GO<=GO+1'b1;
end
else
C1<=C1+1'b1;
end
14: //输入设备地址并将读写位置为读
begin
D1<=8'b1101_0001;
i<=5'd2;
end
15,16,17,18,19,20,21,22: //读取从设备上报的数据
begin
isQ=0;
if(FHALF)
D1[23-i]<=SDA;
if(C1==0)
rSCL<=1'b0;
if(C1==FHALF)
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
23: //应答位判断
begin
isQ=0;
if(C1==FHALF)
isACK<=SDA;
if(C1==0)
rSCL<=1'b0;
if(C1==FHALF)
rSCL<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1;
end
else
C1<=C1+1'b1;
end
24:
begin
if(isACK!=0)
begin
i<=5'b0;
GO<=5'b0;
end
else
i<=i+1;
end
25:
begin
if(C1==0)
begin
rSCL<=1'b0;
rSDA<=1'b0;
end
if(C1==FQUARTER)
rSCL<=1'b1;
if(C1==FHALF)
rSDA<=1'b1;
if(C1==FCLK-1)
begin
C1<=8'b0;
i<=i+1'b1;
end
else
C1<=C1+1'b1;
end
26:
begin
isDONE<=1'b1;
i<=i+1'b1;
end
27:
begin
isDONE<=1'b0;
i<=5'b0;
end
endcase
end
assign SCL=rSCL;
assign SDA=isQ?rSDA:1'bZ;
assign oDONE=isDONE;
assign oDATA=D1;
endmodule
|
|