dht11上板子没反应?(FPGA)

有上拉电阻

状态机和时序图一致

用示波器看波形发现板子发出20ms低电平的开始信号后检测不到传感器的响应,一直重复发起始信号后延时等待的部分

两个传感器都是这样

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/05/31 17:26:55
// Design Name: 
// Module Name: dht11
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module dht11_drive(
input sys_clk,
input rst_n,
inout dht11,//dht11单总线
output reg [31:0] data_valid //有效数据
);

//parameter define
parameter POWER_ON_NUM =1000_000; //上电延时等待时间,单位us
//状态机各个状态
parameter st_power_on_wait = 3'd0; //上电延时等待
parameter st_low_20ms = 3'd1; //主机发送20ms低电平
parameter st_high_13us = 3'd2; //主机释放总线13us
parameter st_rec_low_83us = 3'd3; //接收83us低电平响应
parameter st_rec_high_87us = 3'd4; //等待87us高电平(准备接收数据)
parameter st_rec_data = 3'd5; //接收40位数据
parameter st_delay = 3'd6; //延时等待,延时完成后重新操作DHT11

//reg define
reg [2:0] cur_state ; //当前状态
reg [2:0] next_state ; //下一个状态

reg [4:0] clk_cnt ; //分频计数器
reg clk_1m ; //1Mhz时钟
reg [20:0] us_cnt ; //1微秒计数器
reg us_cnt_clr ; //1微秒计数器清零信号

reg [39:0] data_temp ; //缓存接收到的数据
reg step ; //数据采集状态
reg [5:0] data_cnt ; //接收数据用计数器

reg dht11_buffer; //DHT11输出信号
reg dht11_d0 ; //DHT11输入信号寄存器0
reg dht11_d1 ; //DHT11输入信号寄存器1

//wire define
wire dht11_pos ; //DHT11上升沿
wire dht11_neg ; //DHT11下降沿

//*****************************************************
//** main code
//*****************************************************
assign dht11 = dht11_buffer;
assign dht11_pos = ~dht11_d1 & dht11_d0; //采集上升沿
assign dht11_neg = dht11_d1 & ~dht11_d0; //采集下降沿

//得到1Mhz分频时钟
//系统时钟为50M通过偶分频得到1M时钟即50分频
//用计数器从0技术到50/2-1 偶分频N/2-1
//该项目使用1M分频是因为DHT11时序主要以us为单位
always @ (posedge sys_clk or negedge rst_n)

begin
 if (!rst_n)
   begin
     clk_cnt <= 5'd0;
     clk_1m <= 1'b0;
   end
  else if (clk_cnt < 5'd24)
           clk_cnt <= clk_cnt + 1'b1;
    else begin
         clk_cnt <= 5'd0;
         clk_1m <= ~ clk_1m;
    end
end

//对DHT11输入信号连续寄存两次,用于边沿检测
always @ (posedge clk_1m or negedge rst_n)
 begin
    if (!rst_n)
      begin
        dht11_d0 <= 1'b1;
        dht11_d1 <= 1'b1;
      end
    else begin
       dht11_d0 <= dht11;
       dht11_d1 <= dht11_d0;
     end
end

//1微秒计数器
always @ (posedge clk_1m or negedge rst_n)
 begin
     if (!rst_n)
        us_cnt <= 21'd0;
     else if (us_cnt_clr)
        us_cnt <= 21'd0;
     else
        us_cnt <= us_cnt + 1'b1;
end

//状态跳转
always @ (posedge clk_1m or negedge rst_n)
 begin
    if (!rst_n)
     cur_state <= st_power_on_wait;//上电延时等待
    else
     cur_state <= next_state;
 end

//状态机读取DHT11数据
 always @ (posedge clk_1m or negedge rst_n)
  begin
   if(!rst_n)
     begin
       next_state <= st_power_on_wait;
       data_temp <= 40'd0;
       step <= 1'b0;
       us_cnt_clr <= 1'b0;
       data_cnt <= 6'd0;
       dht11_buffer <= 1'bz;
      end
    else
       begin
         case (cur_state)
//上电后延时1秒等待DHT11稳定
           st_power_on_wait:
              begin
                if(us_cnt < POWER_ON_NUM) //没有达到上电延迟时间1s
                   begin
                     dht11_buffer <= 1'bz; //空闲状态释放总线
                     us_cnt_clr <= 1'b0;
                   end
                 else
                   begin //进入下一状态,清零us计数器
                     next_state <= st_low_20ms;
                     us_cnt_clr <= 1'b1;
                    end
         end
//FPGA发送起始信号(20ms的低电平)
            st_low_20ms: //1
                begin
                  if(us_cnt < 20000)
				     begin
                       dht11_buffer <= 1'b0; //起始信号为低电平
                       us_cnt_clr <= 1'b0;
                     end
                  else
 				    begin
                       dht11_buffer <= 1'bz; //起始信号结束后释放总线
                       next_state <= st_high_13us;
                       us_cnt_clr <= 1'b1;
                     end
                 end
//等待DHT11的响应信号(等待10~20us)
            st_high_13us://2
                begin
                  if (us_cnt < 20)
     				  begin
                       us_cnt_clr <= 1'b0;
                            if(dht11_neg)
                                begin //检测到DHT11响应信号
                                   next_state <= st_rec_low_83us;
                                   us_cnt_clr <= 1'b1;
                                end
     				  end
                  else //超过20us未响应,重新进入延时
                      next_state <= st_delay;
                end
//等待DHT11的83us低电平响应信号结束
            st_rec_low_83us: //3
                begin
                  if(dht11_pos)
     				  next_state <= st_rec_high_87us;
     			end
//DHT11拉高87us通知FPGA准备接收数据
            st_rec_high_87us:
     			begin
                  if(dht11_neg)
     				  begin //准备时间结束
     				      next_state <= st_rec_data;
     				      us_cnt_clr <= 1'b1;
     				  end
     		      else
      				  begin //高电平准备接收数据
      				      data_cnt <= 6'd0;
      				      data_temp <= 40'd0;
      				      step <= 1'b0;
      				  end
      		    end
//连续接收40位数据
            st_rec_data:
    			begin
                  case(step)
0: begin //接收数据低电平
if(dht11_pos) begin
step <= 1'b1;
us_cnt_clr <= 1'b1;
end
else //等待数据低电平结束
us_cnt_clr <= 1'b0;
end
1: begin //接收数据高电平
if(dht11_neg) begin
data_cnt <= data_cnt + 1'b1;
//判断接收数据为0/1
if(us_cnt < 60)
data_temp <= {data_temp[38:0],1'b0};//移位寄存器写法
else
data_temp <= {data_temp[38:0],1'b1};
step <= 1'b0;
us_cnt_clr <= 1'b1;
end
else //等待数据高电平结束
us_cnt_clr <= 1'b0;
end
endcase
            if(data_cnt == 40) begin  //数据传输结束,验证校验位
                next_state <= st_delay;
                if(data_temp[7:0] == data_temp[39:32] + data_temp[31:24] 
                                     + data_temp[23:16] + data_temp[15:8])
                    data_valid <= data_temp[39:8];  
            end
        end 
            //完成一次数据采集后延时2s
        st_delay:begin
            if(us_cnt < 2000_000)
                us_cnt_clr <= 1'b0;
            else begin                //延时结束后重新发送起始信号
                next_state <= st_low_20ms;      
                us_cnt_clr <= 1'b1;
            end
        end
    endcase
	end 
end
endmodule

 

您好,请问您最后解决这个问题了吗,我现在也遇见了同样的问题