求大神给一份PCF8591的基于FPGA的verilog的IIc控制程序
1条回答
- qq_35523202 2018-11-20 13:30关注
module DAC_I2C
(
input clk_in, // system clock
input rst_n_in, // system reset, active lowinput [7:0] dac_data, // dac data input output reg dac_done, // dac transfer done output scl_out, // I2C CLK inout sda_out // I2C SDA
);
parameter CNT_NUM = 30; localparam IDLE = 3'd0; localparam MAIN = 3'd1; localparam START = 3'd2; localparam WRITE = 3'd3; localparam ACK = 3'd4; localparam STOP = 3'd5; //generate clk_200khz clock reg clk_200khz; reg [5:0] cnt_200khz; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) begin cnt_200khz <= 5'd0; clk_200khz <= 1'b0; end else if(cnt_200khz >= CNT_NUM-1) begin cnt_200khz <= 5'd0; clk_200khz <= ~clk_200khz; end else begin cnt_200khz <= cnt_200khz + 1'b1; end end //reg [7:0] cnt_wave; reg scl_out_r; reg sda_out_r; reg [3:0] cnt_main; reg [7:0] data_wr; reg [1:0] cnt_start; reg [4:0] cnt_write; reg [1:0] cnt_ack; reg [1:0] cnt_stop; reg [2:0] state = IDLE; reg [2:0] state_back = IDLE; always@(posedge clk_200khz or negedge rst_n_in) begin if(!rst_n_in) begin //cnt_wave <= 8'd0; scl_out_r <= 1'd1; sda_out_r <= 1'd1; cnt_main <= 4'd0; cnt_start <= 2'd0; cnt_write <= 5'd0; cnt_ack <= 2'd0; cnt_stop <= 2'd0; state <= IDLE; state_back <= IDLE; end else begin case(state) IDLE:begin scl_out_r <= 1'd1; sda_out_r <= 1'd1; cnt_main <= 4'd0; cnt_start <= 2'd0; cnt_write <= 5'd0; cnt_ack <= 2'd0; cnt_stop <= 2'd0; state <= MAIN; state_back <= MAIN; end MAIN:begin //if(cnt_main >= 4'd8) cnt_main <= 4'd0; //write in byte mode if(cnt_main >= 4'd6) cnt_main <= 4'd5; //write in chain mode else cnt_main <= cnt_main + 1'b1; case(cnt_main) 4'd0: begin state <= START; end 4'd1: begin data_wr <= 8'h90; state <= WRITE; end 4'd2: begin state <= ACK; end 4'd3: begin data_wr <= 8'h40; state <= WRITE; end 4'd4: begin state <= ACK; end //4'd5: begin data_wr <= cnt_wave; cnt_wave <= cnt_wave+8'd8; state <= WRITE; end 4'd5: begin data_wr <= dac_data; state <= WRITE; dac_done <= 1'b0;end 4'd6: begin state <= ACK; dac_done <= 1'b1; end 4'd7: begin state <= STOP; end 4'd8: begin state <= IDLE; end default: state <= IDLE; endcase end START:begin if(cnt_start >= 2'd2) cnt_start <= 1'b0; else cnt_start <= cnt_start + 1'b1; case(cnt_start) 2'd0: begin sda_out_r <= 1'b1; scl_out_r <= 1'b1; end 2'd1: begin sda_out_r <= 1'b0; end 2'd2: begin scl_out_r <= 1'b0; state <= MAIN; end default: state <= IDLE; endcase end WRITE:begin if(cnt_write >= 5'd16) cnt_write <= 1'b0; else cnt_write <= cnt_write + 1'b1; case(cnt_write) //transfer data with i2c 5'd0: begin sda_out_r <= data_wr[7]; scl_out_r <= 1'b0; end 5'd1: begin scl_out_r <= 1'b1; end 5'd2: begin sda_out_r <= data_wr[6]; scl_out_r <= 1'b0; end 5'd3: begin scl_out_r <= 1'b1; end 5'd4: begin sda_out_r <= data_wr[5]; scl_out_r <= 1'b0; end 5'd5: begin scl_out_r <= 1'b1; end 5'd6: begin sda_out_r <= data_wr[4]; scl_out_r <= 1'b0; end 5'd7: begin scl_out_r <= 1'b1; end 5'd8: begin sda_out_r <= data_wr[3]; scl_out_r <= 1'b0; end 5'd9: begin scl_out_r <= 1'b1; end 5'd10: begin sda_out_r <= data_wr[2]; scl_out_r <= 1'b0; end 5'd11: begin scl_out_r <= 1'b1; end 5'd12: begin sda_out_r <= data_wr[1]; scl_out_r <= 1'b0; end 5'd13: begin scl_out_r <= 1'b1; end 5'd14: begin sda_out_r <= data_wr[0]; scl_out_r <= 1'b0; end 5'd15: begin scl_out_r <= 1'b1; end 5'd16: begin scl_out_r <= 1'b0; state <= MAIN; end default: state <= IDLE; endcase end ACK:begin if(cnt_ack >= 2'd3) cnt_ack <= 1'b0; else cnt_ack <= cnt_ack + 1'b1; case(cnt_ack) //read bit 0 2'd0: begin sda_out_r <= 1'bz; end 2'd1: begin scl_out_r <= 1'b1; end 2'd2: begin if(sda_out) state <= IDLE; else state <= state; end 2'd3: begin scl_out_r <= 1'b0; state <= MAIN; end default: state <= IDLE; endcase end STOP:begin if(cnt_stop >= 2'd2) cnt_stop <= 1'b0; else cnt_stop <= cnt_stop + 1'b1; case(cnt_stop) 2'd0: begin sda_out_r <= 1'b0; end 2'd1: begin scl_out_r <= 1'b1; end 2'd2: begin sda_out_r <= 1'b1; state <= MAIN; end default: state <= IDLE; endcase end endcase end end assign scl_out = scl_out_r; assign sda_out = sda_out_r;
endmodule
解决 2无用
悬赏问题
- ¥15 请教一下各位,为什么我这个没有实现模拟点击
- ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
- ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
- ¥20 有关区间dp的问题求解
- ¥15 多电路系统共用电源的串扰问题
- ¥15 slam rangenet++配置
- ¥15 有没有研究水声通信方面的帮我改俩matlab代码
- ¥15 ubuntu子系统密码忘记
- ¥15 保护模式-系统加载-段寄存器
- ¥15 电脑桌面设定一个区域禁止鼠标操作