基于FPGA的温湿度检测

初始化部分就不过多赘述,我会给出对应的文件,我只说明这部分里面涉及到使用的代码部分

1、数据的读取和校验

数据的读取和检验代码如下

always @ (posedge clk_us)if (data_temp[7:0] == data_temp[39:32] + data_temp[31:24] + data_temp[23:16] + data_temp[15:8])data <= data_temp[39:8];else data <= data;

在这个代码之前,我们已经用data_temp存储了温湿度传感器传输的数据

数据组成

温湿度传感器传过来的是一个四十位的数据,具体的意义对应如下

(1)data_temp[39:32]——湿度整数部分

(2)data_temp[31:24]——湿度小数部分

(3)data_temp[23:16]——温度整数部分

(4)data_temp[15:8]——温度小数部分

(5)data_temp[7:0]——校验和

校验思路

校验思路根据数据本身的意义进行,如果数据正确

则数据的校验和部分等于其他所有部分的相加

数据读取

数据的读取基于校验进行

若校验通过,则将温湿度传感器传回数据的前32位赋值给data[](后八位校验和只用于校验)

若校验不通过,则将data本身的值赋值给data[]

2、数据输出部分

代码部分如下

always @ (posedge clk_us)begindata_out[11:4] <= data[15:8];      // 输出温度的整数部分data_out[3:0] <= data[3:0];        // 输出温度的小数部分data_out[19:12] <= data[31:24];    // 输出湿度的整数部分end

在之前我们已经介绍了温湿度传过来数据的组成,也说了数据读取的部分,所以这里就不再介绍为什么数据的部分的实际意义

3、按键标志位控制数据标志

always @ (posedge sys_clk)if (key_flag == 1'b1)data_flag <= ~data_flag;elsedata_flag <= data_flag;

data_flag是一个标志位,用来选择要显示的是湿度数据还是温度数据。当data_flag为1时,表示选择的是温度数据。 

4、符号输出

温度的数据是带有符号的,也根据温湿度传输过来的数据确定

温度的符号根据温度数据的最高有效位确定

always @ (posedge clk_us)if (data_flag == 1'b1 && data[7] == 1'b1)sign <= 1'b1;else sign <= 1'b0;

5、状态机

状态机状态转换图

 状态机部分代码

always @(posedge clk_us)case (state)WAIT_1S:if (cnt_us == WAIT1S_MAX)state <= START;else state <= WAIT_1S;START:if (cnt_us == LOW_18MS_MSX)state <= DLY_1;else state <= START;DLY_1:if (cnt_us == 20'd10)state <= REPLY;else state <= DLY_1;REPLY:if (dht11_rise == 1'b1 && cnt_low > 80)state <= DLY_2;else if (cnt_us > 1000)state <= START;else state <= REPLY;DLY_2:if (dht11_fall == 1'b1 && cnt_us > 80)state <= RD_DATA;else state <= DLY_2;RD_DATA:if (bit_cnt == 40 && dht11_rise == 1'b1)state <= START;elsestate <= RD_DATA;default: state <= WAIT_1S;endcasealways @(posedge clk_us)case(state)WAIT_1S:if (cnt_us == WAIT1S_MAX)cnt_us <= 20'd0;elsecnt_us <= cnt_us + 1'b1;START:if (cnt_us == LOW_18MS_MSX)cnt_us <= 20'd0;elsecnt_us <= cnt_us + 1'b1;DLY_1:if (cnt_us == 10)cnt_us <= 20'd0;elsecnt_us <= cnt_us + 1'b1;REPLY:if (dht11_rise == 1'b1 && cnt_low > 80)begincnt_low <= 20'd0;cnt_us <= 20'd0;end else if (dht11 == 1'b0)begincnt_low <= cnt_low + 1'b1;cnt_us <= cnt_us + 1'b1;end else if (cnt_us > 1000)begincnt_low <= 20'd0;cnt_us <= 20'd0;end elsebegincnt_low <= cnt_low;cnt_us <= cnt_us + 1'b1;endDLY_2:if (dht11_fall == 1'b1 && cnt_us > 80)cnt_us <= 20'd0;else cnt_us <= cnt_us + 1'b1;RD_DATA:if (dht11_fall == 1'b1 || dht11_rise == 1'b1)cnt_us <= 20'd0;else cnt_us <= cnt_us + 1'b1;default:begincnt_low <= 20'd0;cnt_us <= 20'd0;end endcase

6、模块完整代码

module dht11
(input wire  sys_clk ,input wire  key_flag,inout wire dht11,output reg [19:0] data_out ,output reg sign );parameter WAIT_1S =	6'b000_001,START   =	6'b000_010,DLY_1   =	6'b000_100,REPLY   =	6'b001_000,DLY_2   =	6'b010_000,RD_DATA =	6'b100_000;parameter WAIT1S_MAX = 20'd999_999 ;
parameter LOW_18MS_MSX = 20'd17_999 ;wire dht11_rise ;
wire dht11_fall ;reg clk_us ;
reg [4:0] cnt ;
reg [5:0] state ;
reg [19:0] cnt_us ;
reg [19:0] cnt_low ;
reg  dht11_reg1 ;
reg  dht11_reg2 ; reg [5:0] bit_cnt ;
reg [39:0] data_temp ;
reg [31:0] data ;
reg data_flag ;
reg dht11_en ;
reg dht11_out ;always @(posedge sys_clk)if (cnt == 5'd24)cnt <=5'd0;else cnt <=cnt+ 1'b1;always @(posedge sys_clk)if (cnt == 5'd24)clk_us <= ~clk_us ;else clk_us <=clk_us;always @(posedge clk_us)case (state)WAIT_1S   :if (cnt_us == WAIT1S_MAX)state <= START;else state <=WAIT_1S ;START     :if (cnt_us == LOW_18MS_MSX)state <= DLY_1;else state <=START ;DLY_1     :if (cnt_us ==20'd10)state <= REPLY ;else state <=DLY_1 ;REPLY     :if (dht11_rise == 1'b1&&cnt_low> 80 )state <= DLY_2;else if (cnt_us >1000)state <=START ;else state <= REPLY;DLY_2     :if (dht11_fall == 1'b1 &&cnt_us > 80 )state <= RD_DATA ;else state <= DLY_2 ;RD_DATA   :if (bit_cnt == 40 && dht11_rise == 1'b1)state <= START;elsestate <= RD_DATA;default : state <= WAIT_1S ;endcase //转换时钟
always @(posedge clk_us)case(state)WAIT_1S  :if (cnt_us==WAIT1S_MAX)cnt_us <=20'd 0;elsecnt_us <= cnt_us+1'b1 ;START    :if (cnt_us==LOW_18MS_MSX)cnt_us <=20'd 0;elsecnt_us <= cnt_us+1'b1 ;DLY_1    :if (cnt_us== 10)cnt_us <=20'd 0;elsecnt_us <= cnt_us+1'b1 ;REPLY    :if (dht11_rise == 1'b1&&cnt_low> 80 )begin cnt_low <= 20'd0 ;cnt_us <= 20'd0 ;end else if (dht11 == 1'b0)begin cnt_low <= cnt_low +1'b1;cnt_us <= cnt_us + 1'b1;end else if (cnt_us >1000)begincnt_low <= 20'd0;cnt_us <= 20'd0 ;end else begin cnt_low <= cnt_low ;cnt_us <= cnt_us + 1'b1;end DLY_2    :if (dht11_fall == 1'b1 &&cnt_us > 80 )cnt_us <= 20'd0 ;else cnt_us <= cnt_us +1'b1 ;RD_DATA  :if (dht11_fall ==1'b1||dht11_rise==1'b1 )cnt_us <= 20'd0 ;else cnt_us<= cnt_us +1'b1 ;default  :begincnt_low <= 20'd0;cnt_us <= 20'd0 ;end endcasealways @(posedge clk_us)begin dht11_reg1 <= dht11  ;dht11_reg2 <= dht11_reg1 ;end assign dht11_rise = (~dht11_reg2)&&(dht11_reg1);assign dht11_fall = (dht11_reg2)&&(~dht11_reg1);always @ (posedge clk_us)if (bit_cnt==40 && dht11_rise == 1'b1 )bit_cnt <= 6'b0 ;else if (state ==RD_DATA && dht11_fall==1'b1)bit_cnt <= bit_cnt +1'b1 ;else bit_cnt <= bit_cnt;always @ (posedge clk_us)if (state ==RD_DATA && dht11_fall==1'b1&& cnt_us <= 50 )data_temp[39-bit_cnt] <= 1'b0 ;else if (state ==RD_DATA && dht11_fall==1'b1&& cnt_us >50 )data_temp[39-bit_cnt] <= 1'b1 ;elsedata_temp <= data_temp ;//数据校验部分data_temp[39:32]温度整数部分;data_temp[31:24]湿度小数部分;data_temp[23:16]温度整数部分;	
always @ (posedge clk_us)if (data_temp[7:0] == data_temp[39:32]+ data_temp [31:24] +data_temp[23:16]+data_temp[15:8])data <= data_temp[39:8];else data <= data ;always @ (posedge clk_us)if (state ==START)dht11_en <= 1'b1;elsedht11_en <= 1'b0;always @ (posedge clk_us)dht11_out <=1'b0 ;always @ (posedge sys_clk)if (key_flag == 1'b1)data_flag <= ~ data_flag;elsedata_flag <= data_flag;always @ (posedge clk_us)begindata_out[11:4] <= data[15:8];data_out[3:0] <= data[3:0];data_out[19:12] <= data[31:24] ;end 	  always@(posedge clk_us )//     if(data_flag == 1'b0 ) //湿度小数位为0
//        data_out    <=  data[31:24] * 10;  //为了兼容温度显示的小数,将湿度的个
//		                               //位与十位扩大10倍,小数位为零
//    else    if(data_flag == 1'b1) //温度低四位显示温度小数数据
//        data_out    <=  data[15:8] * 10 + data[3:0];always @ (posedge clk_us)if (data_flag==1'b1 && data[7] == 1'b1)sign <= 1'b1 ;else sign <= 1'b0 ;assign dht11 = (dht11_en == 1) ? 1'b0 : 1'bz ;endmodule

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7 xtrabackup mysql 基本测试(5)mysql 建立 测试 数据库及内容

centos7 xtrabackup mysql 基本测试&#xff08;5&#xff09;mysql 建立 测试 数据库及内容 登录 mysql -u etc -p 1234aA~1创建数据库 名字是company show databases ; create database company;在 company里面 创建表employee use company; DROP TABLE IF EXISTS employ…

vue+canvas画布实现网页签名效果

1、签名自定义组件代码示例&#xff1a; qianMing.vue <template><!-- 容器&#xff0c;包含画布和清除按钮 --><div class"signature-pad-container"><!-- 画布元素&#xff0c;用于用户签名 --><canvasref"canvas" <!--…

C++旋转点坐标计算

/// 获取A点绕B点旋转P度后的新坐标/// </summary>/// <param name"Angle">角度</param>/// <param name"CirPoint">圆心坐标</param>/// <param name"MovePoint">移动点的坐标</param>/// <param…

成为画图大师,用图表讲故事

这些问题你是否遇到过: 项目总结会上&#xff0c;如果用数据呈现你做的价值&#xff1f; 完善详尽的数据分析得出了让人信服的结论&#xff0c;如何呈现在BOSS面前? 我们要的不是数据&#xff0c;而是数据告诉我们的事实 数据很重要&#xff0c;但只是原料&#xff0c;所以…

微服务之服务保护策略【持续更新】

文章目录 线程隔离一、滑动窗口算法二、漏桶算法三、令牌桶算法 面试题1、Sentinel 限流和Gateway限流的区别 线程隔离 两种实现方式 线程池隔离&#xff08;Hystix隔离&#xff09;&#xff0c;每个被隔离的业务都要创建一个独立的线程池&#xff0c;线程过多会带来额外的CPU…

大模型笔记1: Longformer环境配置

论文: https://arxiv.org/abs/2004.05150 首先保证电脑上配置了git. git环境配置: https://blog.csdn.net/Andone_hsx/article/details/87937329 3.1、找到git安装路径中bin的位置&#xff0c;如&#xff1a;D:\Program Files\Git\bin 找到git安装路径中git-core的…

Windows应急响应靶机 - Web3

一、靶机介绍 应急响应靶机训练-Web3 前景需要&#xff1a;小苕在省护值守中&#xff0c;在灵机一动情况下把设备停掉了&#xff0c;甲方问&#xff1a;为什么要停设备&#xff1f;小苕说&#xff1a;我第六感告诉我&#xff0c;这机器可能被黑了。 这是他的服务器&#xff…

Java 并发编程常见问题

1、线程状态它们之间是如何扭转的&#xff1f; 1、谈谈对于多线程的理解&#xff1f; 1、对于多核CPU&#xff0c;多线程可以提升CPU的利用率&#xff1b; 2、对于多IO操作的程序&#xff0c;多线程可以提升系统的整体性能及吞吐量&#xff1b; 3、使用多线程在一些场景下可…

浅谈区块链

区块链是一种分布式数据库技术&#xff0c;也被称为分布式账本技术。它的本质是一个去中心化的数据库&#xff0c;使用密码学相关联产生的数据块串连而成&#xff0c;用于验证其信息的有效性&#xff08;防伪&#xff09;和生成下一个区块。区块链具有“不可伪造”“全程留痕”…

模板方法模式在金融业务中的应用及其框架实现

引言 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它在一个方法中定义一个算法的框架&#xff0c;而将一些步骤的实现延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。在金融业务中&#xff…

DataV大屏组件库

DataV官方文档 DataV组件库基于Vue &#xff08;React版 (opens new window)&#xff09; &#xff0c;主要用于构建大屏&#xff08;全屏&#xff09;数据展示页面即数据可视化&#xff0c;具有多种类型组件可供使用&#xff1a; 源码下载

一文带你了解乐观锁和悲观锁的本质区别!

文章目录 悲观锁是什么&#xff1f;乐观锁是什么&#xff1f;如何实现乐观锁&#xff1f;什么是CAS应用局限性ABA问题是什么&#xff1f; 悲观锁是什么&#xff1f; 悲观锁它总是假设最坏的情况&#xff0c;它会认为共享资源在每次被访问的时候就会出现线程安全问题&#xff0…

AI陪伴产品的情感设计:从孤独感到恋爱感评分:9/10

本文主要阐述三个话题&#xff1a; 1. 市面上有哪些AI陪伴产品&#xff1f; 2. 我们团队要怎么做&#xff1f; 3. 为什么要做&#xff1f; 市面上有哪些陪伴类产品&#xff1f; Role-play&#xff08;角色扮演&#xff09; 在当前市场上&#xff0c;有不少以角色扮演为核心的…

qt文件如何打包成一个独立的exe文件

QT官方给我们安装好了打包软件&#xff0c;就在你QT安装的位置 把这个在cmd打开C:\Qt\6.7.1\mingw_64\bin\windeployqt6.exe&#xff08;或复制地址&#xff09; 然后把要打包项目的exe复制到新的空文件夹&#xff0c;再复制他的地址 按回车后生成新文件 再下载打包软件&#…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 03

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econom…

【地理库 Turf.js】

非常全面的地理库 &#xff0c; 这里枚举一些比较常用&#xff0c;重点的功能&#xff0c; 重点功能 提供地理相关的类&#xff1a;包括点&#xff0c;线&#xff0c;面等类。 测量功能&#xff1a;点到线段的距离&#xff0c;点和线的关系等。 判断功能&#xff1a; 点是否在…

西点领导力:卓越是怎样练成的

今天刚看了一个美国西点军校第50任校长&#xff1a;罗伯克卡斯伦的《为什么跟西点军校学领导力培养》这个演讲。从中受益良多&#xff0c;于是我就去了解了一下这位校长以及西点军校。 西点军校 西点军校&#xff08;United States Military Academy, USMA&#xff09;&#…

C++感受12-Hello Object 派生版

不变的功能&#xff0c;希望直接复用原有代码&#xff1b;变化的功能&#xff0c;希望在分开的代码里实现。 派生的基本概念和目的如何定义派生类以及创建派生对象派生对象的生死过程 0. 课堂视频 ff14-HelloObject-派生版 1. 派生的基本概念与目的 编程&#xff0c;或者说软…

Linux线程同步【拿命推荐版】

目录 &#x1f6a9;引言 &#x1f6a9;听故事&#xff0c;引概念 &#x1f6a9;生产者消费者模型 &#x1f680;再次理解生产消费模型 &#x1f680;挖掘特点 &#x1f6a9;条件变量 &#x1f680;条件变量常用接口 &#x1f680;条件变量的原理 &#x1f6a9;引言 上一篇…

解锁横向招聘:创新您的人才搜索

技能差距仍然是面试官面临的问题之一。在这些空缺职位中&#xff0c;很难找到合适的技能候选人&#xff0c;特别是高级职位或以上职位。另一方面&#xff0c;申请人也发现很难找到一份适合自己的工作&#xff0c;因为他们抱怨工作要求太窄或太具体。在具有挑战性的职位招聘环境…