`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 13:59:21 10/19/2020 // Design Name: // Module Name: DS18B20 // Project Name: // Target Devices: // Tool versions: // Description: //+125 0000 0111 1101 0000 07D0h //+85* 0000 0101 0101 0000 0550h //+25.0625 0000 0001 1001 0001 0191h //+10.125 0000 0000 1010 0010 00A2h //+0.5 0000 0000 0000 1000 0008h //0 0000 0000 0000 0000 0000h //-0.5 1111 1111 1111 1000 FFF8h //-10.125 1111 1111 0101 1110 FF5Eh //-25.0625 1111 1110 0110 1111 FE6Fh //-55 1111 1100 1001 0000 FC90h ////////////////////////////////////////////////////////////////////////////////// module ds18b20_temp( input clk , //40_000_000 input rstn , inout dq , output reg signed[15:0] temp_data //LSB =0.625 C ); parameter FRE = 40 ;// //clk为40M时钟,若clk为50M,则 FRE=50; parameter INIT = 3'b000 , //Gray code WR_CMD = 3'b001 , WAIT = 3'b011 , INIT_AGAIN = 3'b010 , RD_CMD = 3'b110 , RD_TEMP = 3'b111 ; localparam WR_CC_44 = 16'h44cc ; localparam WR_CC_BE = 16'hbecc ; localparam cnt_max = FRE[31:1]-1 ; localparam WAIT_TEMP_CNT = 20'd750_000 ;//750ms reg flag ; reg [15:0] data_reg ; reg [2:0] state ; reg clk_1us ; reg [31:0] cnt_1us ; reg dq_en ; reg dq_reg ; reg [19:0] cnt ; reg [3:0] bit_cnt ; assign dq = dq_en ? dq_reg : 1'bz; always@(posedge clk,negedge rstn) if(!rstn) cnt_1us<=32'b0; else if(cnt_1us==cnt_max) cnt_1us<=32'b0; else cnt_1us<=cnt_1us+1'b1; always@(posedge clk,negedge rstn) if(!rstn) clk_1us<=1'b0; else if(cnt_1us==cnt_max) clk_1us<=~clk_1us; else clk_1us<=clk_1us; always@(posedge clk_1us,negedge rstn) if(!rstn) begin dq_en <=1'b1; dq_reg <=1'b0; state <=INIT; cnt <=20'd0; flag <=1'b0; bit_cnt <=4'b0; data_reg <=16'd0; temp_data<=12'b0; end else case(state) INIT :begin //if(cnt==16'd999)begin //for sim if(cnt==16'd9999) cnt <=20'd0; else if(cnt==16'd999&&flag)begin cnt <=20'd0; state<=WR_CMD; end else begin cnt <=cnt+1'd1; state<=INIT; end //------------------ if(cnt==16'd9999)begin dq_en <=1'b1; dq_reg<=1'b0; end //else if(cnt==16'd499)begin else if(cnt==16'd599)begin dq_en <=1'b0; dq_reg<=1'b0; end else begin dq_en <=dq_en; dq_reg<=dq_reg; end //------------------ // if(cnt==20'd570)//&&dq==1'b0) if(cnt==20'd670)//&&dq==1'b0) flag<= ~dq; else if(cnt==20'd999) flag<=1'b0; else flag<=flag; end /* INIT :begin //if(cnt==16'd999)begin //for sim if(cnt==16'd999&&flag)begin cnt <=20'd0; state<=WR_CMD; end else begin cnt <=cnt+1'd1; state<=INIT; end //------------------ if(cnt==16'd499)begin dq_en <=1'b0; dq_reg<=1'b0; end else begin dq_en <=dq_en; dq_reg<=dq_reg; end //------------------ if(cnt==20'd570)//&&dq==1'b0) flag<= ~dq; else if(cnt==20'd999) flag<=1'b0; else flag<=flag; end */ WR_CMD :begin if(cnt==20'd64 && bit_cnt==4'd15) begin bit_cnt<=4'd0; state<=WAIT; end else if(cnt==20'd64) begin bit_cnt<=bit_cnt+1'd1; state<=WR_CMD; end else begin bit_cnt<=bit_cnt; state<=WR_CMD; end //------------------ if(cnt==20'd64 && bit_cnt==4'd15) cnt<=20'd0; else if(cnt==20'd64) cnt<=20'd0; else cnt<=cnt+1'd1; //------------------ if(WR_CC_44[bit_cnt]==1'b0 && cnt<=20'd62) begin dq_en <=1'b1; dq_reg<=1'b0; end else if(WR_CC_44[bit_cnt]==1'b1 && cnt<=20'd1) begin dq_en <=1'b1; dq_reg<=1'b0; end else begin dq_en <=1'b0; dq_reg<=1'b0; end end WAIT : if(cnt==WAIT_TEMP_CNT) begin dq_en <=1'b1; dq_reg<=1'b0; cnt<=20'd0; state<=INIT_AGAIN; end else begin dq_en <=1'b1; dq_reg<=1'b1; cnt<=cnt+1'd1; state<=WAIT; end INIT_AGAIN :begin if(cnt==16'd999&&flag) //if(cnt==16'd999) //for sim begin cnt <=20'd0; state<=RD_CMD; end else begin cnt <=cnt+1'd1; state<=INIT_AGAIN; end //------------------ if(cnt==16'd499) begin dq_en <=1'b0; dq_reg<=1'b0; end else begin dq_en <=dq_en; dq_reg<=dq_reg; end //------------------ if(cnt==20'd570)//&&dq==1'b0) flag<=~dq; else if(cnt==20'd999) flag<=1'b0; else flag<=flag; end RD_CMD :begin if(cnt==20'd64 && bit_cnt==4'd15) begin bit_cnt<=4'd0; state<=RD_TEMP; end else if(cnt==20'd64) begin bit_cnt<=bit_cnt+1'd1; state<=RD_CMD; end else begin bit_cnt<=bit_cnt; state<=RD_CMD; end //------------------ if(cnt==20'd64 && bit_cnt==4'd15) cnt<=20'd0; else if(cnt==20'd64) cnt<=20'd0; else cnt<=cnt+1'd1; //------------------ if(WR_CC_BE[bit_cnt]==1'b0 && cnt<=20'd62) begin dq_en <=1'b1; dq_reg<=1'b0; end else if(WR_CC_BE[bit_cnt]==1'b1 && cnt<=20'd1) begin dq_en <=1'b1; dq_reg<=1'b0; end else begin dq_en <=1'b0; dq_reg<=1'b0; end end RD_TEMP :begin if(cnt==20'd64 && bit_cnt==4'd15) cnt <=20'd0; else if(cnt==20'd64) cnt<=20'd0; else cnt<=cnt+1'd1; //------------------ if(cnt<=20'd1|| (cnt==20'd64 && bit_cnt==4'd15)) begin dq_en <=1'b1; dq_reg<=1'b0; end else begin dq_en <=1'b0; dq_reg<=1'b0; end //------------------ if(cnt==20'd64 && bit_cnt==4'd15) begin bit_cnt<=4'd0; state<=INIT; end else if(cnt==20'd64) begin bit_cnt<=bit_cnt+1'd1; state<=RD_TEMP; end else begin bit_cnt<=bit_cnt; state<=RD_TEMP; end //------------------ if(cnt==20'd8) data_reg<={dq,data_reg[15:1]}; else data_reg<=data_reg; //------------------ if(cnt==20'd64 && bit_cnt==4'd15) temp_data<=data_reg; else temp_data<=temp_data; end default: state<=INIT; endcase /* wire[33:0]SYNC_OUT; wire[35:0]CONTROL0; wire[35:0]CONTROL1; wire[149:0]TRIG0; vio u_vio ( .CONTROL (CONTROL0), // INOUT BUS [35:0] .CLK (clk), // IN .SYNC_OUT (SYNC_OUT) // OUT BUS [33:0] ); icon u_icon ( .CONTROL0 (CONTROL0), // INOUT BUS [35:0] .CONTROL1 (CONTROL1) // INOUT BUS [35:0] ); ila u_ila ( .CONTROL (CONTROL1), // INOUT BUS [35:0] .CLK (clk), // IN .TRIG0 (TRIG0) // IN BUS [39:0] ); assign TRIG0[2:0] = state ; assign TRIG0[21:3] = cnt ; assign TRIG0[22] = dq ; */ endmodule