当前位置: 首页 > news >正文

【 DHT11 温湿度传感器】使用STC89C51读取发送到串口、通过时序图编写C语言

文章目录

  • DHT11 温湿度传感器
    • 概述
    • 接线
    • 数据传送
      • 通讯过程时序图
      • 检测模块是否存在
    • 代码实现
    • 总结
      • 对tmp = tmp << 1;的理解
      • 对sendByte(datas[0]/10 + 0x30);的理解

DHT11 温湿度传感器

使用80C51单片机通过读取HDT11温湿度传感的数据,发送到串口。
通过时序图编写相应的C语言代码。
总结

概述

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,应用领域:暖通空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制.

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,内部由一个 8 位单片机控制一个电阻式感湿元件和一个 NTC 测温元件。DHT11 虽然也是采用单总线协议,但是该协议与 DS18B20 的单总线协议稍微有些不同之处。
相比于 DS18B20 只能测量温度,DHT11 既能检测温度又能检测湿度,不过 DHT11 的精度和测量范围都要低于 DS18B20,其温度测量范围为 0~50℃,误差在±2℃;湿度的测量范围为 20%~90%RH(Relative Humidity 相对湿度—指空气中水汽压与饱和水汽压的百分比),误差在±5%RH。DHT11 电路很简单,只需要将 DATA 引脚连接单片机的一个 I/O 即可,不过该引脚需要上拉一个 5K 的电阻,DHT11 的供电电压为 3~5.5V

在这里插入图片描述

接线

在这里插入图片描述

数据传送

只有一根数据线DATA,单片机发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验

通讯过程时序图

在这里插入图片描述

因为只有一根数据线DATA,所以传输数据“0”、“1”是根据高电平的时间长短得出

检测模块是否存在

根据如下时序图,做通信初始化,并检测模块是否存在,功能是否正常
在这里插入图片描述

代码实现

#include "reg52.h"
#include "intrins.h"sbit ledOne = P3^7;
sbit dht = P3^3;//模块的data插在p3.3char datas[5];sfr AUXR = 0x8E;void UartInit(void)		//9600bps@11.0592MHz
{AUXR = 0x01;SCON = 0x40; //配置串口工作方式1,REN不使能接收TMOD &= 0xF0;TMOD |= 0x20;//定时器1工作方式位8位自动重装TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器
}
void sendByte(char data_msg)
{SBUF = data_msg;while(!TI);TI = 0;
}void sendString(char* str)
{while( *str != '\0'){sendByte(*str);str++;}
}void Delay30ms()		//@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay60us()		//@11.0592MHz
{unsigned char i;i = 25;while (--i);
}void Delay1000ms()		//@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void DHT11_Start()
{dht = 1;dht = 0;//延时30msDelay30ms();dht = 1;while(dht);while(!dht);while(dht);
}
void Delay40us()		//@11.0592MHz
{unsigned char i;_nop_();i = 15;while (--i);
}void Read_Data_From_DHT()
{int i;//轮int j;//每一轮读多少次char tmp;char flag;DHT11_Start();for(i= 0;i < 5;i++){//:while(!dht)       有效数据都是高电平,持续时间不一样,50us读,低电平0 高电平for(j=0;j<8;j++){while(!dht);//等待卡g点Delay40us();if(dht == 1){flag = 1;while(dht);}else{flag = 0;} tmp = tmp << 1;tmp |= flag;}datas[i] = tmp;}}void main()
{ledOne = 1;UartInit();Delay1000ms();Delay1000ms();while(1){Delay1000ms();Read_Data_From_DHT();	sendString("H:");sendByte(datas[0]/10 + 0x30);//43 a sendByte(datas[0]%10 + 0x30);sendByte('.');sendByte(datas[1]/10 + 0x30);//43 a sendByte(datas[1]%10 + 0x30);	sendString("\r\n");	sendString("T:");sendByte(datas[2]/10 + 0x30);//43 a sendByte(datas[2]%10 + 0x30);	sendByte('.');sendByte(datas[3]/10 + 0x30);//43 a sendByte(datas[3]%10 + 0x30);			sendString("\r\n");		}
}

总结

对tmp = tmp << 1;的理解

对这两句代码的理解

			tmp = tmp << 1;tmp |= flag;

这两句代码用于将读取到的每一位数据拼接成一个字节(8位)的数据

  • tmp 是一个字节变量,用于存储一个完整的8位数据。
  • tmp << 1 表示将 tmp 中的所有位向左移动一位。
  • 左移一位相当于将 tmp 的二进制数乘以2,并在最右边的位填充0。例如,如果 tmp 当前值是 00101100,左移一位后变成
    01011000。
    这一步的作用是为即将读取的下一位数据腾出位置。
  • flag 是一个位变量,用于存储当前读取到的1位数据(值为0或1)
  • tmp |= flag 表示将 flag 的值合并到 tmp 的最右边的位。
  • | 是按位或操作符,如果对应位置上有一个1,结果就是1。

例如,如果 tmp 当前值是 01011000,而 flag 是 1,那么 tmp |= flag 后的值是 01011001。如果 flag 是 0,那么 tmp 仍然是 01011000
假设 tmp 初始为 00000000,我们依次读取8位数据 1, 0, 1, 1, 0, 0, 1, 0。每次读取位后进行左移和按位或操作:
读取第1位(flag = 1):tmp = tmp << 1 -> tmp = 00000000,tmp |= 1 -> tmp = 00000001
读取第2位(flag = 0):tmp = tmp << 1 -> tmp = 00000010,tmp |= 0 -> tmp = 00000010
读取第3位(flag = 1):tmp = tmp << 1 -> tmp = 00000100,tmp |= 1 -> tmp = 00000101

对sendByte(datas[0]/10 + 0x30);的理解

  • datas[0]/10:

这是一个整数除法操作,将 datas[0] 的十位数提取出来。例如,假设 datas[0] = 43,则 43 / 10 = 4。

  • 0x30:

在ASCII编码中,数字字符是从 0x30(‘0’)开始的。‘0’ 的ASCII码是 0x30,‘1’ 的ASCII码是 0x31,以此类推。
因此,通过加上 0x30,我们将数值4转换为字符’4’。具体地,4 + 0x30 = 0x34,对应的ASCII字符是’4’。

这种写法 sendByte(datas[0]/10 + 0x30); 的目的是将数值转换为对应的ASCII字符,以便通过串口发送并在终端显示。具体地,通过除以10和取模10操作分别提取十位和个位,并加上 0x30 将数值转换为字符'0'到'9'的ASCII码,

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python 二进制求和
  • 第五章:卷-将磁盘挂载到容器
  • linux环境交叉编译openssl库,以使Qt支持https
  • (二)原生js案例之数码时钟计时
  • 使用ChatGPT来撰写和润色学术论文的教程(含最新升级开桶ChatGpt4教程)​​
  • MySQL事务管理(上)
  • C++ versions less than C++14/11 are not supported.报错
  • vscode 远程 Ubuntu 系统
  • 神经网络模型实现(训练、测试)
  • 我的创作一周年纪念日
  • Spring Boot 中使用 Resilience4j 实现弹性微服务的简单了解
  • 自学鸿蒙HarmonyOS的ArkTS语言<十>@BuilderParam装饰器
  • ERROR: No matching distribution found for execjs
  • 《逻辑006:页面跳转并传参》
  • 麻省理工学院 - MIT - 线性代数学习笔记
  • JS 中的深拷贝与浅拷贝
  • 分享的文章《人生如棋》
  • [译]前端离线指南(上)
  • Apache Spark Streaming 使用实例
  • Brief introduction of how to 'Call, Apply and Bind'
  • C++类中的特殊成员函数
  • ES6简单总结(搭配简单的讲解和小案例)
  • JavaScript的使用你知道几种?(上)
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java编程基础24——递归练习
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • js作用域和this的理解
  • MySQL QA
  • PHP那些事儿
  • XForms - 更强大的Form
  • 浮现式设计
  • 简析gRPC client 连接管理
  • 警报:线上事故之CountDownLatch的威力
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 小程序开发中的那些坑
  • 硬币翻转问题,区间操作
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $NOIp2018$劝退记
  • (C)一些题4
  • (C语言)fgets与fputs函数详解
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (独孤九剑)--文件系统
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (三十五)大数据实战——Superset可视化平台搭建
  • (实战篇)如何缓存数据
  • (四)汇编语言——简单程序
  • (五)c52学习之旅-静态数码管
  • (一)Dubbo快速入门、介绍、使用