`timescale 1ns/1ns module Sht10 ( input wire rst, //系统复位信号 input wire clk, //20MHZ时钟 input wire rd , input wire rd_clk, // input wire clk1ms, output reg scl, //串行时钟信号 inout wire sda, //串行数据、地址 output reg rw_rdy, //读写完成信号 output reg[7:0] RH_Data, // output reg[11:0] T_Data );
//定义常量 /**************下面定义的常量更改时需谨慎******************************/ localparam CNT_WD = 5; localparam US_CNT_VALUE = 20; //localparam dlt = 1; //parameter localparam dlt = 1; localparam IDLE = 4'b0000, START = 4'b0001, WRITE = 4'b0011, READ = 4'b0010, STOP = 4'b0110, DEVICE_ADDR = 4'b0100, BYTE_ADDR = 4'b0101, write_delay = 4'b0111, read_delay = 4'b1000, Ts = 4'b1100, Ts1 =4'b1101, Ts2 =4'b1110, Ts3 =4'b1111, Ts4 =4'b0100;
localparam INSTEP0 = 2'b00, INSTEP1 = 2'b01, INSTEP2 = 2'b10, INSTEP3 = 2'b11;
localparam FREE_OPERATE = 2'b00, WRITE_OPERATE = 2'b01, PRE_READ_OPERATE = 2'b10, READ_OPERATE = 2'b11; localparam rst_cmd=4'd0; localparam status_read_cmd=4'd1; localparam status_write_cmd=4'd2; localparam data_acq_cmd=4'd3;
/**************上面定义的常量更改时需谨慎******************************/
//定义变量 reg iic_sda_enb; reg sda_buf,rd_clk_buf; reg[7:0] data; reg[23:0] ts_data; reg[1:0] rd_clk_syn; reg[7:0] cnt; reg[3:0] state;
reg rst_rdy,tran_rdy;
//逻辑实现 //双向端口逻辑转换 assign sda = (iic_sda_enb)?sda_buf:1'bz;
// 串口时钟缓存 always @(posedge clk or posedge rst) begin if (rst) begin rd_clk_buf<=1'b0; rd_clk_syn<=2'b00; end else begin rd_clk_buf<=rd_clk; rd_clk_syn<={rd_clk_buf,rd_clk}; end end // 数据采集 always @(posedge clk or posedge rst) begin if (rst) begin iic_sda_enb<=1'b0; scl<=1'b0; state<=IDLE; cnt<=8'd0; end else case (state) IDLE: begin scl<=rd_clk; iic_sda_enb<=1'b1; if (rd_clk_syn==2'b01) begin cnt<=cnt+1'b1; sda_buf<=1'b1; end else if ((cnt==8'd10) && (rd_clk==1'b1)) begin cnt<=8'd0; state<=Ts; ts_data<=18'b000001111000000001; end end Ts: begin iic_sda_enb<=1'b1; scl<=1'b1; if (rd_clk_syn==2'b10) begin sda_buf<=1'b0; state<=Ts1; end end Ts1: begin if (rd_clk_syn==2'b01) begin sda_buf<=1'b0; state<=Ts2; end end Ts2: begin iic_sda_enb<=1'b1; scl<=1'b0; if (rd_clk_syn==2'b10) begin sda_buf<=1'b0; state<=Ts3; end end Ts3: begin iic_sda_enb<=1'b1; scl<=1'b1; if (rd_clk_syn==2'b01) begin state<=START; sda_buf<=1'b1; end end Ts4: begin iic_sda_enb<=1'b1; scl<=1'b1; if (rd_clk_syn==2'b10) begin state<=START; end end START: begin scl<=rd_clk; iic_sda_enb<=1'b1; if (rd_clk_syn==2'b01) begin cnt<=cnt+1'b1; sda_buf<=ts_data[17]; ts_data<={ts_data[16:0],1'b0}; end else if ((cnt==8'd18) && (rd_clk==1'b0)) begin cnt<=8'd0; state<=WRITE; ts_data<=14'b10001000001011; end end WRITE: begin scl<=rd_clk; iic_sda_enb<=1'b1; if (rd_clk_syn==2'b01) begin cnt<=cnt+1'b1; sda_buf<=ts_data[13]; ts_data<={ts_data[12:1],1'b0}; end else if ((cnt==8'd14) && (rd_clk==1'b0)) begin cnt<=8'd0; state<=write_delay; end end write_delay: begin if(cnt==8'd80) begin cnt<=8'd0; state<=read_delay; end else if(clk1ms==1'b1) cnt<=cnt+1'b1; end read_delay: begin iic_sda_enb<=1'b0; if(rd_clk==1'b1) begin scl<=1'b1; if (sda==1'b0) state<=READ; else state<=IDLE; end end default: begin iic_sda_enb<=1'b0; scl<=1'b0; state<=IDLE; end endcase end endmodule
|