完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
DM2016操作,当读取DM2016里面的eeprom数据的时候,在写入空间地址时没有接收到应答,但是写入芯片地址有收到应答。并且在对eeprom写入数据的时候,无论什么时候都有应答,就是在读eeprom的时候没有应答,有没有有过这个经验啊?
module eeprom ( Clk, //时钟 Rst_n, //复位 iic_data_in, //要存储的数据 iic_data_out, //读出的数据 iic_addr, //存储地址 iic_base, //芯片固定指令 iic_en, //写入数据的指令 iic_end, iic_scl, iic_sda ); input Clk; input Rst_n; input [7:0]iic_data_in; //要存入eeprom的数据 input [7:0]iic_addr; //地址 input [7:0]iic_base; //1010_0000 写 1010_0001读 input iic_en; //写入eeprom的数据指令 output reg iic_scl; //iic时钟引脚 output reg [7:0]iic_data_out; //读取eeprom的数据 output reg iic_end; //iic一次操作结束 inout iic_sda; //iic数据线 parameter START = 4'd0; parameter BASE = 4'd1; parameter ADDRESS = 4'd2; parameter WRITE_DATA = 4'd3; parameter READ_DATA=4'd4; parameter ACK_BASE =4'd5; parameter ACK_ADDRESS = 4'd6; parameter ACK_DATA = 4'd7; parameter STOP = 4'd8; reg clk_iic; reg [5:0]cnt; reg iic_sda_reg; reg ack_stop; reg [4:0]count; reg [3:0]state; reg flag_sda; always @ (posedge Clk or negedge Rst_n) ////clk_iic 1.5us反转一次 begin if(!Rst_n) begin clk_iic <= 0; cnt <= 0; end else if( (cnt >= 6'd59) || (ack_stop)) begin cnt <= 0; clk_iic <= ~clk_iic; end else cnt <= cnt + 1'b1; end always @ (posedge Clk or negedge Rst_n) begin if(!Rst_n) begin count <= 5'd31; end else if( iic_en ) begin count <= 0; end else if(ack_stop) begin count<=5'd2; end else if( (cnt == 6'd59) && (count<=5'd25) ) count <= count+1'b1; end always @ (posedge Clk or negedge Rst_n) //iic_scl begin if(!Rst_n) begin iic_scl<=1'b1; end else begin case(count) 5'd2,5'd4,5'd6,5'd8,5'd10,5'd12,5'd14,5'd16,5'd18,5'd20: begin iic_scl <= 1'b0;end 5'd3,5'd5,5'd7,5'd9,5'd11,5'd13,5'd15,5'd17,5'd19: begin iic_scl <= 1'b1;end default:iic_scl <= 1'b1; endcase end end always @ (posedge Clk or negedge Rst_n) //sda begin if(!Rst_n) begin iic_sda_reg <= 1'b1; end else if( ((state == START) ) &&(count == 5'd1) ) begin iic_sda_reg <= 1'b0; end else if(state == BASE ) //在下降沿后的1us改变 && cnt == 6'd39 begin if(cnt == 6'd39) case(count) 5'd2: iic_sda_reg <= iic_base[7]; 5'd4: iic_sda_reg <= iic_base[6]; 5'd6: iic_sda_reg <= iic_base[5]; 5'd8: iic_sda_reg <= iic_base[4]; 5'd10: iic_sda_reg <= iic_base[3]; 5'd12: iic_sda_reg <= iic_base[2]; 5'd14: iic_sda_reg <= iic_base[1]; 5'd16: iic_sda_reg <= iic_base[0]; // 5'd20: iic_sda_reg <= 1'b1; default:;// iic_sda_reg <= 1; endcase end else if(state == ADDRESS ) //&& cnt == 6'd39 begin if(cnt == 6'd39) case(count) 5'd2: iic_sda_reg <= iic_addr[7]; 5'd4: iic_sda_reg <= iic_addr[6]; 5'd6: iic_sda_reg <= iic_addr[5]; 5'd8: iic_sda_reg <= iic_addr[4]; 5'd10: iic_sda_reg <= iic_addr[3]; 5'd12: iic_sda_reg <= iic_addr[2]; 5'd14: iic_sda_reg <= iic_addr[1]; 5'd16: iic_sda_reg <= iic_addr[0]; 5'd20: iic_sda_reg <= 1'b1; // default: iic_sda_reg <= 1; endcase end else if(state == WRITE_DATA ) //&& cnt == 6'd39 begin if(cnt == 6'd39) case(count) 5'd2: iic_sda_reg <= iic_data_in[7]; 5'd4: iic_sda_reg <= iic_data_in[6]; 5'd6: iic_sda_reg <= iic_data_in[5]; 5'd8: iic_sda_reg <= iic_data_in[4]; 5'd10: iic_sda_reg <= iic_data_in[3]; 5'd12: iic_sda_reg <= iic_data_in[2]; 5'd14: iic_sda_reg <= iic_data_in[1]; 5'd16: iic_sda_reg <= iic_data_in[0]; 5'd20: iic_sda_reg <= 1'b1; // 5'd18: iic_sda_reg <= 1'b1; // default: iic_sda_reg <= 1; endcase end else if(state == READ_DATA ) //&& cnt == 6'd39 begin if(cnt == 6'd39) case(count) 5'd2: iic_data_out[7] <=iic_sda; 5'd4: iic_data_out[6] <=iic_sda; 5'd6: iic_data_out[5] <=iic_sda; 5'd8: iic_data_out[4] <=iic_sda; 5'd10: iic_data_out[3] <=iic_sda; 5'd12: iic_data_out[2] <=iic_sda; 5'd14: iic_data_out[1] <=iic_sda; 5'd16: iic_data_out[0] <=iic_sda; //default: iic_sda_reg <= 1; endcase end else iic_sda_reg <= 1'b1; end always @ (posedge Clk or negedge Rst_n) //write sda begin if(!Rst_n) begin state <= START; ack_stop <= 1'b0; iic_end <= 1'b0; // iic_sda_reg<=1'b1; flag_sda <= 1'b0; end else begin case(state) START: begin ack_stop <= 1'b0; iic_end <= 1'b0; flag_sda <= 1'b0; //SDA输出 if(count == 5'd1) begin state <= BASE;end end BASE: //芯片地址 begin flag_sda <= 1'b0; //SDA输出 if(count==5'd18) begin state<=ACK_BASE; flag_sda <= 1'b1; //SDA输入,即高阻态 end end ACK_BASE: begin if( ((!iic_sda) & (iic_scl)) && (count==5'd19) ) //scl begin state<=ADDRESS; // ack_stop<=1'b1; end end ADDRESS: begin if( (count == 5'd20) ) //&& (cnt == 6'd59) ack_stop <= 1'b1; if( (count == 5'd2) ) begin ack_stop <= 1'b0; //此时count<=0; flag_sda <= 1'b0; //SDA输出 end if( (count==5'd18) && (ack_stop==0) ) // begin state<=ACK_ADDRESS; flag_sda <= 1'b1; //SDA输入,即高阻态 end end ACK_ADDRESS: begin if( (!iic_sda) & (iic_scl) && (count==5'd19) ) begin // ack_stop<=1'b1; if(iic_base[0]) state <= READ_DATA; //READ_DATA else state <= WRITE_DATA; //WRITE_DATA end else if(count >=5'd20) //没有接收到ack信号 begin state <= ADDRESS; flag_sda <= 1'b0; //SDA输出 end end READ_DATA: begin if(count == 5'd20) ack_stop<=1'b1; if(count == 5'd2) begin ack_stop <= 1'b0; flag_sda <= 1'b1; //SDA输出 end if( (count==5'd18) && (ack_stop==0) ) begin state<=ACK_DATA; flag_sda <= 1'b1; //SDA输入,即高阻态 end end WRITE_DATA: begin if(count == 5'd20) ack_stop<=1'b1; if(count == 5'd2 ) begin ack_stop <= 1'b0; flag_sda <= 1'b0; //SDA输出 end if(count==5'd18 ) begin state<=ACK_DATA; flag_sda <= 1'b1; //SDA输入,即高阻态 end end ACK_DATA: begin if( ((!iic_sda) & (iic_scl)) && (count==5'd19) ) //scl begin state<=STOP; flag_sda <= 1'b1; //SDA输入,即高阻态 end end STOP: begin flag_sda <= 1'b0; //SDA输出 // iic_sda_reg<=1'b1; iic_end <= 1'b1; state <= START; end // WAIT: // begin // iic_end <= 1'b0; // end endcase end end assign iic_sda = flag_sda?1'bz:iic_sda_reg; endmodule |
|
相关推荐
|
|
1403 浏览 1 评论
助力AIoT应用:在米尔FPGA开发板上实现Tiny YOLO V4
1053 浏览 0 评论
2474 浏览 1 评论
2177 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
2445 浏览 0 评论
1918 浏览 52 评论
6020 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 20:29 , Processed in 0.620200 second(s), Total 65, Slave 47 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号