DHT11温湿度传感器的FPGA驱动代码

Tama ·
更新时间:2024-09-20
· 804 次阅读

一、说明书主要内容 1、产品概述

在这里插入图片描述

2、接口说明

串行接口:
在这里插入图片描述

3、通讯过程

在这里插入图片描述
从通讯时序可以看出,读取一帧传感器数据的时序为:
主机将data线拉低至少18ms,然后拉高20-40us。然后主机释放data线给dht11,dht11将data线拉低80us作为响应信号,再拉高80us,若主机检测到正确的响应信号,读操作即可开始。
读操作
dht11将data线拉低50us,然后拉高,如果这一位表示‘0’,则拉高时间为26-28us,若表示‘1’,则拉高时间为70us

Verilog驱动 //作者:杨成煜 //日期:2020/4/6 //==================defines===================== //`define SIM module dht11( //================System Signal================ input clk, input rst_n, //================Interface==================== inout data, input rd_req, output reg[39:0] data_rd ); //================parameters=================== `ifndef SIM localparam CNT_30US = 1499; localparam CNT_20MS = 999_999; localparam CNT_80US = 3999; localparam CNT_50US = 2499; localparam CNT_70US = 3499; localparam CNT_28US = 1399; `else `endif //state localparam S_IDLE = 5'b00001; localparam S_START= 5'b00010; localparam S_DHT_ACK=5'b00100; localparam S_DHT_SEND_DATA = 5'b01000; localparam S_CHECK_DATA_BIT = 5'b10000; //================System regs================== reg DATA; reg[19:0] cnt_20ms; reg[10:0] cnt_30us; reg[11:0] cnt_80us; reg[11:0] cnt_50us; reg[11:0] cnt_70us; reg cnt_dht_ack_bit; reg flag_rd; reg[3:0] state; reg rd_req_t0; reg rd_req_t1; wire trig_rd_rq; reg data_t0; reg data_t1; wire data_pedge; wire data_nedge; wire flag_check_data_bit; reg flag_check_data_done; reg[5:0] cnt_data_bit; reg flag_cnt_30us_en; //================Main Codes=================== //flag_cnt_30us_en always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) flag_cnt_30us_en <= 1'b0; else if(state==S_START&&cnt_20ms==CNT_20MS) flag_cnt_30us_en <= 1'b1; else if(state==S_START&&cnt_30us==CNT_30US) flag_cnt_30us_en <= 1'b0; end //cnt_data_bit always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_data_bit <= 'd0; else if(cnt_data_bit==6'd39&&flag_check_data_done==1'b1) cnt_data_bit <= 'd0; else if(flag_check_data_done==1'b1) cnt_data_bit <= cnt_data_bit + 1'b1; end //flag_check_data_done always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) flag_check_data_done <= 1'b0; else if(state==S_CHECK_DATA_BIT&&data_nedge==1'b1) flag_check_data_done <= 1'b1; else flag_check_data_done <= 1'b0; end //flag_check_data_bit assign flag_check_data_bit = (state==S_CHECK_DATA_BIT&&flag_check_data_done==1'b0)?1'b1:1'b0; //data_rd always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) data_rd <= 'd0; else if(state==S_CHECK_DATA_BIT) if(cnt_70us<=CNT_28US&&flag_check_data_done==1'b1) data_rd <= {data_rd[38:0],1'b0}; else if(cnt_70us<=CNT_80US&&flag_check_data_done==1'b1) data_rd <= {data_rd[38:0],1'b1}; end // DATA; always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) DATA <= 1'b1; else if(state==S_IDLE||state==S_START) if(trig_rd_rq==1'b1&&flag_rd==1'b0) DATA <= 1'b0; else if(cnt_20ms==CNT_20MS) DATA <= 1'b1; end //cnt_20ms always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_20ms <= 'd0; else if(state==S_START) if(cnt_20ms==CNT_20MS) cnt_20ms <= 'd0; else cnt_20ms <= cnt_20ms + 1'b1; else cnt_20ms <= 'd0; end //cnt_30us always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_30us <= 'd0; else if(state==S_START&&flag_cnt_30us_en==1'b1) if(cnt_30us==CNT_30US) cnt_30us <= 'd0; else cnt_30us <= cnt_30us + 1'b1; else cnt_30us <= 'd0; end //cnt_80us always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_80us <= 'd0; else if(state==S_DHT_ACK) if(cnt_80us==CNT_80US) cnt_80us <= 'd0; else cnt_80us <= cnt_80us + 1'b1; else cnt_80us <= 'd0; end //cnt_50us always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_50us <= 'd0; else if(state==S_DHT_SEND_DATA) if(cnt_50us==CNT_50US) cnt_50us <= 'd0; else cnt_50us <= cnt_50us + 1'b1; else cnt_50us <= 'd0; end //cnt_70us always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_70us <= 'd0; else if(state==S_CHECK_DATA_BIT) if(cnt_70us==CNT_70US) cnt_70us <= 'd0; else cnt_70us <= cnt_70us + 1'b1; else cnt_70us <= 'd0; end //cnt_dht_ack_bit always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) cnt_dht_ack_bit <= 'd0; else if(state==S_DHT_ACK) if(cnt_dht_ack_bit==1'b0&&cnt_80us==CNT_80US) cnt_dht_ack_bit <= 1'b1; else if(cnt_dht_ack_bit==1'b1&&cnt_80us==CNT_80US) cnt_dht_ack_bit <= 1'b0; end //flag_rd always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) flag_rd <= 1'b0; else if(state==S_IDLE) if(trig_rd_rq==1'b1) flag_rd <= 1'b1; else flag_rd <= 1'b0; else if(state==S_CHECK_DATA_BIT) if(cnt_data_bit==6'd39&&flag_check_data_done==1'b1) flag_rd <= 1'b0; else flag_rd <= 1'b1; end assign data = (state==S_IDLE||state==S_START&&cnt_30us<=CNT_30US)?DATA:1'bz; //rd_req_temp always @(posedge clk)begin rd_req_t0 <= rd_req; rd_req_t1 <= rd_req_t0; end assign trig_rd_rq = rd_req_t0&(~rd_req_t1); //data_temp always @(posedge clk)begin if(state==S_CHECK_DATA_BIT) data_t0 <= data; data_t1 <= data_t0; end assign data_nedge = (~data_t0)&data_t1; assign data_pedge = data_t0&(~data_t1); //state machine always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0) state <= S_IDLE; else case(state) S_IDLE:begin if(trig_rd_rq==1'b1) state <= S_START; else state <= S_IDLE; end S_START:begin if(cnt_30us==CNT_30US&&cnt_20ms==20'd0) state <= S_DHT_ACK; else state <= S_START; end S_DHT_ACK:begin if(cnt_80us==1999&&data==1'b0&&cnt_dht_ack_bit==1'b0) state <= S_DHT_ACK; else if(cnt_80us==1999&&cnt_dht_ack_bit==1'b1) state <= S_DHT_SEND_DATA; else if(cnt_80us==1999&&data==1'b1&&cnt_dht_ack_bit==1'b0) state <= S_IDLE; end S_DHT_SEND_DATA:begin if(cnt_50us==CNT_50US) state <= S_CHECK_DATA_BIT; else state <= S_DHT_SEND_DATA; end S_CHECK_DATA_BIT:begin if(cnt_data_bit==6'd39&&flag_check_data_bit==1'b1&&flag_check_data_done==1'b1) state <= S_IDLE; else if(flag_check_data_bit==1'b1&&flag_check_data_done==1'b1) state <= S_DHT_SEND_DATA; else state <= S_CHECK_DATA_BIT; end default:state <= S_IDLE; endcase end endmodule
作者:杨少侠qy



温湿度 dht11 dht 温湿度传感器 fpga 传感器

需要 登录 后方可回复, 如果你还没有账号请 注册新账号