FPGA project : dht11 温湿度传感器

news2024/12/23 20:50:09

没有硬件,过几天上板测试。

 

 

 

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

 其他模块都是之前的,就不发了。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018568.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

72、Spring Data JPA 的 Specification 动态查询

Specification&#xff1a;规范、规格 ★ Specification查询 它也是Spring Data提供的查询——是对JPA本身 Criteria 动态查询 的包装。▲ 为何要有动态查询 页面上常常会让用户添加不同的查询条件&#xff0c;程序就需要根据用户输入的条件&#xff0c;动态地组合不同的查询…

外星人入侵游戏-(创新版)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

不同类型程序的句柄研究

先做一个winform程序&#xff1b;随便放几个控件&#xff1b; 用窗口句柄查看工具看一下&#xff1b;form和上面的每个控件都有一个句柄&#xff1b; 然后看一下记事本&#xff1b;记事本一共包含三个控件&#xff0c;各自有句柄&#xff1b; 这工具的使用是把右下角图标拖到要…

服务器迁移:无缝过渡指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

基于SSM+Vue的高校实验室管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

线程的方法(未完成)

线程的方法 1、sleep(long millis) 线程休眠&#xff1a;让执行的线程暂停一段时间&#xff0c;进入计时等待状态。 static void sleep(long millis):调用此方法后&#xff0c;当前线程放弃 CPU 资源&#xff0c;在指定的时间内&#xff0c;sleep 所在的线程不会获得可运行的机…

如何使用Java语言判断出geek是字符串参数类型,888是整数参数类型,[hello,world]是数组参数类型,2.5是双精度浮点数类型?

如何使用Java语言判断出geek是字符串参数类型&#xff0c;888是整数参数类型&#xff0c;[hello,world]是数组参数类型&#xff0c;2.5是双精度浮点数类型&#xff1f; Java是一种静态类型的编程语言&#xff0c;这意味着我们需要在编译时为变量指定具体的类型。但是&#xff…

web应用及微信小程序版本更新检测方案实践

背景&#xff1a; 随着项目体量越来越大&#xff0c;用户群体越来越多&#xff0c;用户的声音也越来越明显&#xff1b;关于应用发版之后用户无感知&#xff0c;导致用户用的是仍然还是老版本功能&#xff0c;除非用户手动刷新&#xff0c;否则体验不到最新的功能&#xff1b;这…

ICCV 2023 | MPI-Flow:从单视角构建的多平面图像中学习光流

ICCV 2023 | MPI-Flow&#xff1a;从单视角构建的多平面图像中学习光流 引言&#xff1a;主要贡献&#xff1a;Motivation&#xff1a;算法细节&#xff1a;Optical Flow Data GenerationIndependent Object MotionsDepth-Aware Inpainting 实验结果&#xff1a; 来源&#xff…

QT:使用分组框、单选按钮、普通按钮、标签、行编辑器、垂直分布、水平分布做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QRadioButton> //单选按钮 #include <QGroupBox> //分组框 #include <QHBoxLayout> //水平布局 #include <QVBoxLayout> //垂直布局 #include <QPushButton>…

MFC主框架和视类PreCreateWindow()函数学习

在VC生成的单文档应用程序中&#xff0c;主框架类和视类均具有PreCreateWindow函数&#xff1b; 从名字可知&#xff0c;可在此函数中添加一些代码&#xff0c;来控制窗口显示后的效果&#xff1b; 并且它有注释说明&#xff0c; Modify the Window class or styles here by…

RHCSA 重定向、vim练习题

1.重定向练习题 (1)新建一个文件redirect.txt&#xff0c;并在其中写入20210804RHCSA,保存并退出 先输入命令 [rootlocalhost ~]# vim redirect.txt进入vim编辑器后&#xff0c;按快捷键“i”进入编辑模式&#xff0c;再写入数据&#xff0c;写完之后按“esc"键退出编辑…

python 采用selenium+cookies 获取登录后的网页

百度网页由于需要登陆手机短信验证。比较麻烦 这里我采用先人工登录百度账号&#xff0c;然后将百度账号的相关cookies保存下来 然后采用selenium动态登录网页 整体代码如下 from selenium import webdriverimport timeoptions webdriver.ChromeOptions()options.add_argu…

LLM 08-分布式训练

LLM 08-分布式训练 8.1 为什么分布式训练越来越流行 近年来&#xff0c;深度学习被广泛应用到各个领域&#xff0c;包括计算机视觉、语言理解、语音识别、广告推荐等。在这些不同的领域中&#xff0c;一个共同的特点就是模型规模越来越大&#xff0c;比如 GPT-3 模型的参数量达…

华为云云耀云服务器L实例评测|基于L实例使用Docker部署MySQL服务并连接MySQL—phpMyAdmin管理工具

文章目录 一、云耀云服务器产品优势1、智能不卡顿2、价优随心用3、上手更简单4、管理更省心 二、远程连接云耀云服务器L实例三、安装Docker、docker-compse1、docker安装2、docker-compose安装 四、方法① 使用Docker安装部署MySQL服务五、方法② 使用docker-compse安装部署MyS…

2023年 python结合excel实现快速画图(零基础快速入门)

目录 1.适用人群 2.环境配置 3.基本用法 3.1 数据读取 3.2 数据分析 3.3 数据组装 3.4 制表&#xff1a; 4.快速提升 5.效果展示 1.适用人群 电脑有python环境&#xff0c;会python基本使用&#xff0c;需要短时间内完成大量画图任务的数据分析的人群。&#xff08;有…

AlexNet——训练花数据集

目录 一、网络结构 二、创新点分析 三、知识点 1. nn.ReLU(inplace) 2. os.getcwd与os.path.abspath 3. 使用torchvision下的datasets包 4. items()与dict()用法 5. json文件 6. tqdm 7. net.train()与net.val() 四、代码 AlexNet是由Alex Krizhevsky、Ilya S…

深入学习 Redis Cluster - 基于 Docker、DockerCompose 搭建 Redis 集群,处理故障、扩容方案

目录 一、基于 Docker、DockerCompose 搭建 Redis 集群 1.1、前言 1.2、编写 shell 脚本 1.3、执行 shell 脚本&#xff0c;创建集群配置文件 1.4、编写 docker-compose.yml 文件 1.5、启动容器 1.6、构建集群 1.7、使用集群 1.8、如果集群中&#xff0c;有节点挂了&am…

基于springboot+vue的养老院管理系统 前后端分离项目

养老院管理系统 前后端分离项目 后端技术&#xff1a;springbootmybatis-plusredismysql 前端&#xff1a;vue3.0elementui-plus 【人员管理】 用户管理 客户管理【药品食品管理】 药品管理 食品管理【报修管理】【外出管理】外出管理 访客管理【留言管理】【新闻管理】新闻…

服务器杀掉死进程

清掉服务器上的死进程 查看服务器使用情况 nvidia-smi发现并没有显示进程&#xff0c;那应该是有死进程。 查看占用情况 ps aux会显示如上图的进程列表。 PID进程号STAT状态(S休眠R运行Z死掉了)TIME占用时间(过长的有问题)COMMAND进程启动命令(应该能帮助回忆起这是什么程…