基于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)
  begin
    data_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;
  else
    data_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;
            else
                state <= RD_DATA;
        default: state <= WAIT_1S;
    endcase


always @(posedge clk_us)
    case(state)
        WAIT_1S:
            if (cnt_us == WAIT1S_MAX)
                cnt_us <= 20'd0;
            else
                cnt_us <= cnt_us + 1'b1;
        START:
            if (cnt_us == LOW_18MS_MSX)
                cnt_us <= 20'd0;
            else
                cnt_us <= cnt_us + 1'b1;
        DLY_1:
            if (cnt_us == 10)
                cnt_us <= 20'd0;
            else
                cnt_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)
            begin
                cnt_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:
        begin
            cnt_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;
		else
		   state <= 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;
		  else
		   cnt_us <= cnt_us+1'b1 ;
	   START    :
	     if (cnt_us==LOW_18MS_MSX)
		   cnt_us <=20'd 0;
		  else
		   cnt_us <= cnt_us+1'b1 ;
	   DLY_1    :
	     if (cnt_us== 10)
		   cnt_us <=20'd 0;
		  else
		   cnt_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)
		    begin
              cnt_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  :
	        begin
              cnt_low <= 20'd0;
              cnt_us <= 20'd0 ;
			end 
	endcase
	

	
always @(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 ;
   else
     data_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;
      else
	    dht11_en <= 1'b0;

always @ (posedge clk_us)
      dht11_out <=1'b0 ;




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

 always @ (posedge clk_us)

	  begin
	  
	  data_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.mfbz.cn/a/740149.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQLite3的使用

14_SQLite3 SQLite3是一个嵌入式数据库系统&#xff0c;它的数据库就是一个文件。SQLite3不需要一个单独的服务器进程或操作系统&#xff0c;不需要配置&#xff0c;这意味着不需要安装或管理&#xff0c;所有的维护都来自于SQLite3软件本身。 安装步骤 在Linux上安装SQLite…

AI数据分析:集中度分析和离散度分析

在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本编写的任务&#xff0c;具体步骤如下&#xff1a; 读取Excel表格&#xff1a;"F:\AI自媒体内容\AI行业数据分析\toolify月榜\toolify2023年-2024年月排行榜汇总数据.xlsx&qu…

【PADS】软件下载安装、PADS—Altium Designer文件转换

PADS软件学习——软件下载、安装、解析 一、软件下载 PADS&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1J9z-Rl9sLjfnZYwlE3ZLPQ?pwdGLNG 提取码&#xff1a;GLNG解析软件&#xff1a;http://mentor.mr-wu.cn/PADS教学视频&#xff1a;https://www.bilibili.com/v…

“硝烟下的量子”:以色列为何坚持让量子计算中心落地?

自2023年10月7日新一轮巴以冲突爆发以来&#xff0c;支持巴勒斯坦伊斯兰抵抗运动&#xff08;哈马斯&#xff09;的黎巴嫩真主党不时自黎巴嫩南部向以色列北部发动袭击&#xff0c;以军则用空袭和炮击黎南部目标进行报复&#xff0c;双方在以黎边境的冲突持续至今。 冲突走向扑…

Django教程(001):安装及快速上手

1.1 Django安装 pip install django安装之后 c:\python39-python.exe-Scripts-pip.exe-django-admin.exe【安装django之后&#xff0c;工具&#xff0c;创建django项目】-Lib-内置模块-site-packages-flask-django(安装django之后&#xff0c;【django框架源码】)如下图&…

springboot 网上商城系统-计算机毕业设计源码08789

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设网上商城系统。 本设…

HTTPS 代理的优点和缺点是什么?

HTTPS&#xff08;超文本安全传输协议&#xff09;作为一种基于HTTP加上SSL安全层的网络通信协议&#xff0c;已经成为互联网上广泛使用的IP协议之一。它在保证信息安全和隐私方面具有很多优势&#xff0c;但也存在一些缺点。接下来&#xff0c;我们就来探究一下HTTPS协议的优缺…

导致代理IP延迟高的原因

很多用户在使用代理IP进行网络访问时&#xff0c;可能会遇到代理IP超时的情况&#xff0c;也就是代理IP的延迟过高。代理IP延迟过高会影响用户的网络体验和数据获取效率。因此&#xff0c;了解代理IP延迟过高的原因很重要。以下是导致代理IP延迟过高的一些常见原因&#xff1a;…

相位和展开相位

相位 (Phase) 相位是一个周期信号在一个周期内的位置&#xff0c;通常以角度&#xff08;度或弧度&#xff09;表示。在许多应用中&#xff0c;相位被限制在一个周期内。例如&#xff0c;相位通常被限定在 −180∘到 180∘ 或 0∘ 到 360∘ 之间。 示例 −90∘ 表示信号在周…

fvcore库的一些功能和使用

目录 一、安装fvcore库 二、使用 fvcore是Facebook开源的一个轻量级的核心库&#xff0c;它提供了各种计算机视觉框架中常见且基本的功能。其中就包括了统计模型的参数以及FLOPs等。 项目地址&#xff1a;fvcore 一、安装fvcore库 pip install fvcore 二、使用 1、计算模…

【实物资料包】基于STM32智能台灯设计

【实物资料包】基于STM32智能台灯设计 需要资料的请在文章结尾获取哦~~~~&#xff08;如有问题私信我即可&#xff09; 1.介绍 1 添加wifi模块模块&#xff0c;可通过wifi模块APP或者手动按钮切换自动/手动模式 2 自动模式下&#xff0c;台灯可以感应是否有人落座&#xff0…

干货 | 准备换ERP系统?来看看这篇文章!

当前客户的痛点 在当今竞争激烈的市场环境中&#xff0c;企业面临着诸多挑战和痛点&#xff0c;尤其是在管理和运营方面。让我们以一家中小型制造业企业为例&#xff0c;探讨他们所面临的主要痛点&#xff1a; 分散的数据管理&#xff1a;企业各部门之间信息孤岛严重&#xff…

Ci2451和Ci2454:2.4GHz无线MCU的芯片对比数据资料分析

一、2.4GHz无线MCU芯片的背景介绍 1、开头我们先聊聊&#xff0c;关于南京中科微2.4GHz无线MCU芯片&#xff08;Ci2451、Ci2454、CSM2433)是建立在现有的2.4GHz射频芯片基础上面&#xff0c;它的内部是集成了8位RISC内核&#xff0c;且集成丰富的MCU资源、更小的尺寸可以来满足…

iPhone卡在恢复模式无法退出时,有那些退出恢复模式方法?

iPhone用户有时会遇到需要将手机进入恢复模式的情况。恢复模式可以帮助解决一些软件问题&#xff0c;但如果iPhone卡在恢复模式&#xff0c;不知道如何退出就会非常麻烦。小编将介绍几种iPhone退出恢复模式的方法。 一、苹果手机的恢复模式是什么意思 iPhone的恢复模式是针对i…

React的生命周期函数详解

import React,{Component} from "react";import SonApp from ./sonAppclass App extends Component{state{hobby:爱吃很多好吃的}// 是否要更新数据&#xff0c;这里返回true才会更新数据shouldComponentUpdate(nextProps,nextState){console.log("app.js第一步…

快速排序的实现(3种)

目录 0.快速排序1.Hoare版本1.1基本思想1.2算法描述1.3画图解释1.4问题&#xff1f;1.5代码实现 2.挖坑法2.1算法描述2.2画图解释2.3代码实现 3.先后指针法3.1算法描述3.2画图解释3.3代码实现 4.优化4.1优化方法4.2优化代码 5.非递归实现快排5.1算法描述 0.快速排序 1.时间复杂…

AGV选型要点及步骤,保证企业选择的AGV小车更实用

AGV AGV小车作为智能化物流仓储不可或缺的工具&#xff0c;在制造业得到了广泛的应用&#xff0c;市场需求呈现出井喷式增长。但是AGV市场还存在着很多问题&#xff0c;制造企业在产品选型时往往缺乏正确的引导。 AGV智能仓储 毫无疑问,我们的自动化物流系统已离不开AGV小车了,…

Spring Boot + Vue 全栈开发,都需要哪些前端知识?

Node.js默认安装的npm包和工具的位置&#xff1a;Node.js目录\node_modules 在这个目录下你可以看见 npm目录&#xff0c;npm本身就是被NPM包管理器管理的一个工具&#xff0c;说明 Node.js已经集成了npm工具 #在命令提示符输入 npm -v 可查看当前npm版本 npm -v 二、使用n…

【Android】Android Studio 使用Kotlin写代码时代码提示残缺问题解决

问题描述 Android Studio升级之后&#xff0c;从Android Studio 4.2升级到Android Studio Arctic Fox版本&#xff0c;因为项目比较老&#xff0c;使用的Gradle 版本是3.1.3&#xff0c;这个版本的Android Studio最低支持Gradle 3.1版本&#xff0c;应该算是比较合适的版本。 …

天猫超市卡有什么用?

有时候不知道在网上买什么的时候&#xff0c;恰好就会收到一些猫超卡、京东卡类的礼物 这真是让人苦恼 还好收卡云一直在收这些礼品卡券啊&#xff0c;不然我的大部分礼品卡最后只有过期的份了&#xff01;
最新文章