From 425cc8d00c245669ebe7f6c92fce08ce6f6ff881 Mon Sep 17 00:00:00 2001 From: Gamenight77 Date: Tue, 27 May 2025 13:34:59 +0200 Subject: [PATCH] Refactor DHT11 interface to support 16-bit temperature and humidity data, update checksum handling, and improve state machine logic --- Semaine_7/DHT11/src/verilog/dht11_interface.v | 129 +++++++----------- Semaine_7/DHT11/tests/verilog/tb_dht11.v | 13 +- .../DHT11_UART/IP/verilog/dht11_interface.v | 24 ++-- 3 files changed, 71 insertions(+), 95 deletions(-) diff --git a/Semaine_7/DHT11/src/verilog/dht11_interface.v b/Semaine_7/DHT11/src/verilog/dht11_interface.v index a395468..a77af95 100644 --- a/Semaine_7/DHT11/src/verilog/dht11_interface.v +++ b/Semaine_7/DHT11/src/verilog/dht11_interface.v @@ -1,3 +1,4 @@ +`default_nettype none module dht11_interface #( parameter CLK_FREQ = 27_000_000 )( @@ -6,45 +7,46 @@ module dht11_interface #( input wire i_start, output reg o_dht11_data_ready, output reg o_busy, - output reg [7:0] o_temp_data, - output reg [7:0] o_hum_data, - output reg o_dht11_error + output reg [15:0] o_temp_data, + output reg [15:0] o_hum_data, + output reg [7:0] o_checksum, + output reg [3:0] o_state ); // === DHT11 INTERFACE === // === PARAMÈTRES === localparam T_18MS = CLK_FREQ * 18 / 1_000; // cycles pour 18ms a partir - localparam T_80US = CLK_FREQ * 81 / 1_000_000; - localparam T_79US = CLK_FREQ * 79 / 1_000_000; - localparam T_71US = CLK_FREQ * 71 / 1_000_000; - localparam T_51US = CLK_FREQ * 51 / 1_000_000; + localparam T_80US = CLK_FREQ * 90 / 1_000_000; + localparam T_79US = CLK_FREQ * 70 / 1_000_000; + localparam T_71US = CLK_FREQ * 81 / 1_000_000; + localparam T_51US = CLK_FREQ * 58 / 1_000_000; localparam T_50US = CLK_FREQ * 50 / 1_000_000; localparam T_49US = CLK_FREQ * 49 / 1_000_000; - localparam T_41US = CLK_FREQ * 41 / 1_000_000; - localparam T_28US = CLK_FREQ * 28 / 1_000_000; - localparam T_26US = CLK_FREQ * 26 / 1_000_000; - localparam T_20US = CLK_FREQ * 20 / 1_000_000; + localparam T_40US = CLK_FREQ * 40 / 1_000_000; + localparam T_28US = CLK_FREQ * 32 / 1_000_000; + localparam T_26US = CLK_FREQ * 25 / 1_000_000; + localparam T_20US = CLK_FREQ * 18 / 1_000_000; // === Signal bidirectionnel === reg sig_dir; reg sig_out; - wire sig_in; + reg sig_in; assign io_dht11_sig = sig_dir ? sig_out : 1'bz; // Si sig_dir = 1, on force la valeur de sig_out sur la ligne, sinon on laisse la ligne libre (1'bz) - assign sig_in = io_dht11_sig; + // === REGISTRES === reg [3:0] state; reg [31:0] timer; - reg [7:0] temp_data, hum_data; - reg [7:0] temp_dec, hum_dec, checksum; reg [2:0] bit_count; reg [5:0] bit_index; reg [39:0] raw_data; + reg [15:0] checksum; + // === FSM === localparam IDLE = 4'd0, // Pull up la ligne START = 4'd1, // Pull low 18ms @@ -65,11 +67,11 @@ module dht11_interface #( bit_index = 0; raw_data = 0; o_dht11_data_ready = 0; - o_dht11_error = 0; end // === FSM principale === always @(posedge i_clk) begin + sig_in <= io_dht11_sig; case (state) IDLE: begin @@ -88,7 +90,6 @@ module dht11_interface #( o_busy <= 1; state <= START; o_dht11_data_ready <= 0; - o_dht11_error <= 0; end end @@ -102,112 +103,88 @@ module dht11_interface #( end WAIT_RESPONSE: begin + o_state <= state; + timer <= timer + 1; - if (sig_in == 0) begin - if (timer > T_20US && timer < T_41US) begin - - state <= RESPONSE_LOW; - timer <= 0; - end else begin - state <= ERROR; - end - end else if (timer > T_41US) begin - state <= ERROR; + if (sig_in == 0 && timer > 1) begin + + state <= RESPONSE_LOW; + timer <= 0; + end end RESPONSE_LOW: begin + o_state <= state; timer <= timer + 1; if (sig_in == 1) begin - if (timer > T_79US && timer < T_80US) begin - timer <= 0; - state <= RESPONSE_HIGH; - end else begin - state <= ERROR; - end - end else if (timer > T_80US) begin - state <= ERROR; + + timer <= 0; + state <= RESPONSE_HIGH; + end end RESPONSE_HIGH: begin timer <= timer + 1; - + o_state <= state; if (sig_in == 0) begin - if (timer > T_79US && timer < T_80US) begin + timer <= 0; state <= READ_BITS_LOW; - end else begin - state <= ERROR; - end - end else if (timer > T_80US) begin - state <= ERROR; + end end READ_BITS_LOW: begin + o_state <= state; timer <= timer + 1; + if (sig_in == 1) begin - if (timer > T_49US && timer < T_51US) begin - timer <= 0; - state <= READ_BITS_HIGH; - end else begin - state <= ERROR; - end - end else if (timer > T_51US) begin - state <= ERROR; + timer <= 0; + state <= READ_BITS_HIGH; end end READ_BITS_HIGH: begin // entre 26 et 28us = 0 et ~70us = 1 + o_state <= state; timer <= timer + 1; - if (sig_in == 0) begin - if (timer <= T_26US) begin - state <= ERROR; - end - raw_data <= {raw_data[38:0], (timer > T_28US)}; // 1 si high > ~28us + if (sig_in == 0) begin + + raw_data <= {raw_data[38:0], (timer > T_40US)}; timer <= 0; + bit_index <= bit_index + 1; - if (bit_index == 39) begin // Code a testé ici pour etre sur de capter le dernier bit + if (bit_index == 39) begin state <= DONE; end else begin state <= READ_BITS_LOW; end - end else if (timer > T_71US) begin - state <= ERROR; end end DONE: begin - hum_data <= raw_data[39:32]; - hum_dec <= raw_data[31:24]; - temp_data <= raw_data[23:16]; - temp_dec <= raw_data[15:8]; - checksum <= raw_data[7:0]; - - if (raw_data[7:0] == (raw_data[39:32] + raw_data[31:24] + raw_data[23:16] + raw_data[15:8])) begin - o_hum_data <= raw_data[39:32]; - o_temp_data <= raw_data[23:16]; - o_dht11_data_ready <= 1; - end else begin - o_dht11_error <= 1; - end + o_state <= state; + + o_hum_data <= raw_data[39:24]; + o_temp_data <= raw_data[23:8]; + o_checksum <= raw_data[7:0]; + o_dht11_data_ready <= 1; o_busy <= 0; state <= IDLE; end - ERROR: begin - o_dht11_error <= 1; - state <= IDLE; - end - endcase end + always_comb begin + checksum = raw_data[39:32] + raw_data[31:24] + raw_data[23:16] + raw_data[15:8]; + end + endmodule diff --git a/Semaine_7/DHT11/tests/verilog/tb_dht11.v b/Semaine_7/DHT11/tests/verilog/tb_dht11.v index 82a8f5f..a54af8d 100644 --- a/Semaine_7/DHT11/tests/verilog/tb_dht11.v +++ b/Semaine_7/DHT11/tests/verilog/tb_dht11.v @@ -10,9 +10,9 @@ module tb_dht11; reg dht11_start; wire dht11_data_ready; wire dht11_busy; - wire [7:0] dht11_temp_data; - wire [7:0] dht11_hum_data; - wire dht11_error; + wire [15:0] dht11_temp_data; + wire [15:0] dht11_hum_data; + wire [7:0] o_checksum; // === Simulation du module DHT11 === dht11_model dht11_model ( @@ -30,7 +30,7 @@ module tb_dht11; .o_busy(dht11_busy), .o_temp_data(dht11_temp_data), .o_hum_data(dht11_hum_data), - .o_dht11_error(dht11_error) + .o_checksum(o_checksum) ); pullup(io_dht11_sig); @@ -55,8 +55,9 @@ module tb_dht11; wait(dht11_data_ready); // Attend que les données soient prêtes $display("DHT11 data ready..."); - $display("Température : %d.%d °C", dht11_temp_data); - $display("Humidité : %d.%d %%", dht11_hum_data); + $display("Température : %d.%d °C", dht11_temp_data[15:8], dht11_temp_data[7:0]); + $display("Humidité : %d.%d %%", dht11_hum_data[15:8], dht11_hum_data[7:0]); + $display("Checksum : %d", o_checksum); $display("==== End DHT11 Test ===="); $finish; diff --git a/Semaine_7/DHT11_UART/IP/verilog/dht11_interface.v b/Semaine_7/DHT11_UART/IP/verilog/dht11_interface.v index 45191d1..a77af95 100644 --- a/Semaine_7/DHT11_UART/IP/verilog/dht11_interface.v +++ b/Semaine_7/DHT11_UART/IP/verilog/dht11_interface.v @@ -1,3 +1,4 @@ +`default_nettype none module dht11_interface #( parameter CLK_FREQ = 27_000_000 )( @@ -66,7 +67,6 @@ module dht11_interface #( bit_index = 0; raw_data = 0; o_dht11_data_ready = 0; - o_dht11_error = 0; end // === FSM principale === @@ -90,7 +90,6 @@ module dht11_interface #( o_busy <= 1; state <= START; o_dht11_data_ready <= 0; - o_dht11_error <= 0; end end @@ -108,10 +107,10 @@ module dht11_interface #( timer <= timer + 1; - if (sig_in == 0) begin + if (sig_in == 0 && timer > 1) begin - state <= RESPONSE_LOW; - timer <= 0; + state <= RESPONSE_LOW; + timer <= 0; end end @@ -122,8 +121,8 @@ module dht11_interface #( if (sig_in == 1) begin - timer <= 0; - state <= RESPONSE_HIGH; + timer <= 0; + state <= RESPONSE_HIGH; end end @@ -142,26 +141,25 @@ module dht11_interface #( READ_BITS_LOW: begin o_state <= state; timer <= timer + 1; + if (sig_in == 1) begin - - timer <= 0; - state <= READ_BITS_HIGH; - + timer <= 0; + state <= READ_BITS_HIGH; end end READ_BITS_HIGH: begin // entre 26 et 28us = 0 et ~70us = 1 o_state <= state; timer <= timer + 1; + if (sig_in == 0) begin - raw_data <= {raw_data[38:0], (timer > T_40US)}; timer <= 0; bit_index <= bit_index + 1; - if (bit_index == 40) begin + if (bit_index == 39) begin state <= DONE; end else begin state <= READ_BITS_LOW;