没有硬件,过几天上板测试。
module dht11(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key ,
inout wire dht11 ,
output wire ds ,
output wire oe ,
output wire shcp ,
output wire stcp
);
// 例化连线
wire key_out_w ;
wire [19:00] data_w ;
wire sign_w ;
wire [ 5: 0] point_w ;
wire en_w ;
key_filter key_filter_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key ) ,
.key_out ( key_out_w )
);
dht11_ctrl dht11_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_flag ( key_out_w ) ,
.dht11 ( dht11 ) ,
.data_out ( data_w ) ,
.sign ( sign_w )
);
seg_595_dynamic seg_595_dynamic_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.data ( data_w ) ,
.point ( point_w ) ,
.sign ( sign_w ) ,
.seg_en ( en_w ) ,
.ds ( ds ) ,
.oe ( oe ) ,
.shcp ( shcp ) ,
.stcp ( stcp )
);
endmodule
module dht11_ctrl (
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_flag ,
inout wire dht11 ,
output reg [19:0] data_out ,
output reg sign
);
// reg signal define
// 产生us时钟
reg clk_us ;
reg [4:0] cnt_clk_us ;
// 内部信号(用于产生状态转移条件与输出信号)
reg [19:0] cnt_us ;
reg [ 6:0] cnt_low ;
reg dht11_reg1 ;
reg dht11_reg2 ;
wire dht11_fall ;
wire dht11_rise ;
reg [ 5:0] bit_cnt ;
reg [39:0] data_temp ;
reg [31:0] data ;
reg data_flag ;
// 三态输出
reg dht11_en ;
wire dht11_out ;
// [4:0] cnt_clk_us ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_clk_us <= 5'd0 ;
end else begin
if(cnt_clk_us == 5'd24) begin
cnt_clk_us <= 5'd0 ;
end else begin
cnt_clk_us <= cnt_clk_us + 1'b1 ;
end
end
end
// clk_us ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
clk_us <= 1'b0 ;
end else begin
if(cnt_clk_us == 5'd24) begin
clk_us <= ~clk_us ;
end else begin
clk_us <= clk_us ;
end
end
end
// reg signal define
// 在clk_us时钟域下
// 状态机 三段式写法(现态与次态描述)(状态转移条件描述)(输出信号描述)
localparam WAIT_1S = 6'b000_001 ,
START = 6'b000_010 ,
DELAY_1 = 6'b000_100 ,
REPLAY = 6'b001_000 ,
DELAY_2 = 6'b010_000 ,
RD_DATA = 6'b100_000 ;
reg [5:0] state_c ;
reg [5:0] state_n ;
wire WAIT_1StoSTART ;
wire STARTtoDELAY_1 ;
wire DELAY_1toREPLAY ;
wire REPLAYtoDELAY_2 ;
wire REPLAYtoSTART ;
wire DELAY_2toRD_DATA ;
wire DELAY_2toSTART ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
state_c <= 6'd0 ;
end else begin
state_c <= state_n ;
end
end
always @(*) begin
case (state_c)
WAIT_1S:begin
if(WAIT_1StoSTART) begin
state_n <= START ;
end else begin
state_n <= WAIT_1S ;
end
end
START :begin
if(STARTtoDELAY_1) begin
state_n <= DELAY_1 ;
end else begin
state_n <= START ;
end
end
DELAY_1:begin
if(DELAY_1toREPLAY) begin
state_n <= REPLAY ;
end else begin
state_n <= DELAY_1 ;
end
end
REPLAY :begin
if(REPLAYtoDELAY_2) begin
state_n <= DELAY_2 ;
end else begin
if(REPLAYtoSTART) begin
state_n <= START ;
end else begin
state_n <= REPLAY ;
end
end
end
DELAY_2:begin
if(DELAY_2toRD_DATA) begin
state_n <= RD_DATA ;
end else begin
state_n <= DELAY_2 ;
end
end
RD_DATA:begin
if(DELAY_2toSTART) begin
state_n <= START ;
end else begin
state_n <= RD_DATA ;
end
end
default: state_n <= START ;
endcase
end
// 状态机第二段描述
assign WAIT_1StoSTART = (state_c == WAIT_1S && cnt_us == 20'd999_999) ? 1'b1 : 1'b0 ;
assign STARTtoDELAY_1 = (state_c == START && cnt_us == 20'd17_999) ? 1'b1 : 1'b0 ;
assign DELAY_1toREPLAY = (state_c == DELAY_1 && cnt_us == 20'd10) ? 1'b1 : 1'b0 ;
assign REPLAYtoDELAY_2 = (state_c == REPLAY && dht11_rise == 1'b1 && cnt_low <= 7'd85 && cnt_low >= 7'd81) ? 1'b1 : 1'b0;
assign REPLAYtoSTART = (state_c == REPLAY && dht11_rise == 1'b1 && (cnt_us >= 20'd100 || cnt_us <= 20'd70)) ? 1'b1 : 1'b0 ;
assign DELAY_2toRD_DATA= (state_c == DELAY_2 && dht11_fall == 1'b1 && cnt_us >= 20'd85 && cnt_us <= 20'd88) ? 1'b1 : 1'b0 ;
assign DELAY_2toSTART = (state_c == RD_DATA && bit_cnt == 6'd40 && dht11_rise == 1'b1) ? 1'b1 : 1'b0 ;
// // 内部信号(用于产生状态转移条件与输出信号)
// reg [19:0] cnt_us ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_us <= 20'd0 ;
end else begin
if((state_c == WAIT_1S && cnt_us == 20'd999_999)
|| (state_c == START && cnt_us == 20'd17_999)
|| (state_c == DELAY_1 && cnt_us == 20'd10)
|| (state_c == REPLAY && dht11_rise == 1'b1)
|| (state_c == DELAY_2 && dht11_fall == 1'b1)
|| (state_c == RD_DATA && (dht11_fall || dht11_rise)))begin // 记得最后加大括号
cnt_us <= 20'd0 ;
end else begin
cnt_us <= cnt_us + 1'b1 ;
end
end
end
// reg [ 6:0] cnt_low ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_low <= 7'd0 ;
end else begin
if(state_c == REPLAY && dht11_reg1 == 1'b0) begin
cnt_low <= cnt_low + 1'b1 ;
end else begin
cnt_low <= 7'd0 ;
end
end
end
// reg dht11_reg1 ;
// reg dht11_reg2 ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
dht11_reg1 <= 1'b1 ;
dht11_reg2 <= 1'b1 ;
end else begin
dht11_reg1 <= dht11 ;
dht11_reg2 <= dht11_reg1 ;
end
end
// wire dht11_fall ;
// wire dht11_rise ;
assign dht11_fall = ~dht11_reg1 && dht11_reg2 ;
assign dht11_rise = dht11_reg1 && ~dht11_reg2 ;
// reg [ 5:0] bit_cnt ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
bit_cnt <= 6'd0 ;
end else begin
if(dht11_rise && bit_cnt == 6'd40 ) begin
bit_cnt <= 6'd0 ;
end else begin
if(state_c == RD_DATA && dht11_fall) begin
bit_cnt <= bit_cnt + 1'b1 ;
end else begin
bit_cnt <= bit_cnt ;
end
end
end
end
// reg [39:0] data_temp ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_temp <= 40'd0 ;
end else begin
if(state_c == RD_DATA && dht11_fall && bit_cnt <= 39) begin
if(cnt_us >= 20'd50) begin // 也可以是68
data_temp[39 - bit_cnt] <= 1'b1 ;
end else begin
data_temp[39 - bit_cnt] <= 1'b0 ;
end
end else begin
data_temp <= data_temp ;
end
end
end
// reg [31:0] data ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data <= 32'd0 ;
end else begin
if(data_temp[7:0] == (data_temp[15:8] + data_temp[23:16] + data_temp[31:24] + data_temp[39:32])) begin
data <= data_temp[39:8] ;
end else begin
data <= data ;
end
end
end
// reg data_flag ; sys_clk时钟域下
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_flag <= 1'b0 ;
end else begin
if(key_flag) begin
data_flag <= ~data_flag ;
end else begin
data_flag <= data_flag ;
end
end
end
// // 三态输出
// wire dht11_out ;
assign dht11 = (dht11_en == 1'b1) ? dht11_out : 1'bz ;
assign dht11_out = 1'b0 ;
// reg dht11_en ;
always @(posedge clk_us or negedge sys_rst_n) begin
if(~sys_rst_n) begin
dht11_en <= 1'd0 ;
end else begin
if(state_c == START) begin
dht11_en <= 1'b1 ;
end else begin
dht11_en <= 1'b0 ;
end
end
end
// output signal
// reg [19:0] data_out ,
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_out <= 20'd0 ;
end else begin
if(data_flag == 1'b0) begin // 显示湿度
data_out <= data[31:24] * 16'd10 ;
end else begin
data_out <= data[15:8] * 16'd10 + data[3:0] ;
end
end
end
// reg sign
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
sign <= 1'b0 ;
end else begin
if(key_flag == 1'b1 && data[7] == 1'b1) begin
sign <= 1'b1 ;
end else begin
sign <= 1'b0 ;
end
end
end
endmodule
其他模块都是之前的,就不发了。
文章来源地址https://uudwc.com/A/Y63jy文章来源:https://uudwc.com/A/Y63jy