STC89C52
Windows 10 20H2
Proteus 8 Frofessional v8.9 SP2
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
硬知识
摘自《温湿度模块 DHT11产品手册》、《数字温湿度传感器 DHT22》
典型应用电路中建议连接线长度短于5m时用4.7K上拉电阻,大于5m时根据实际情况降低上拉电阻的阻值。
使用3.3V电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。
每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取2次,但不建议连续多次读取传感器,每次读取传感器间隔大于2秒即可获得准确的数据。
电源部分如有波动,会影响到温度。如使用开关电源,温度就会跳动。传感器上电后,要等待1s以越过不稳定状态,在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。
引脚说明
VDD:供电3.3~5.5V DC
DATA:串行数据,单总线
NC:空脚
GND:接地,电源负极
DHT11
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。
DHT22
DHT22数字温湿度传感器是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT22传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为4针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。
通信协议
器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约4.7kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。
DATA用于微处理器与传感器之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
数据格式:
8bit湿度高位数据+8bit湿度低位数据+8bit温度高位数据+8bit温度低位数据+8bit校验位。
校验位数据定义:
校验位等于8bit湿度高位数据+8bit湿度低位数据+8bit温度高位数据+8bit温度低位数据所得结果的末8位。
数据时序图
用户主机(MCU)发送一次开始信号后,传感器从低功耗模式转换到高速模式,待主机开始信号结束后,传感器发送响应信号,送出40bit的数据,并触发一次信采集。
读取步骤
上电后(上电后要等待1S以越过不稳定状态,在此期间不能发送任何指令),测试环境温湿度数据,并记录数据,同时传感器的DATA数据线由上拉电阻拉高一直保持高电平;此时传感器的DATA引脚处于输入状态,时刻检测外部信号。
微处理器的I/O设置为输出同时输出低电平,且低电平保持时间不能小于18ms(最大不得超过30ms),然后微处理器的I/O设置为输入状态,由于上拉电阻,微处理器的I/O即传感器的DATA数据线也随之变高,等待传感器作出回答信号。
传感器的DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后传感器的DATA引脚处于输出状态,输出83微秒的低电平作为应答信号,紧接着输出87微秒的高电平通知外设准备接收数据,微处理器的I/O此时处于输入状态,检测到I/O有低电平(传感器回应信号)后,等待87微秒的高电平后的数据接收
由传感器的DATA引脚输出40位数据,微处理器根据I/O电平的变化接收40位数据,位数据"0”的格式为:54微秒的低电平和23-27微秒的高电平,位数据"1"的格式为:54微秒的低电平加68-74微秒的高电平。
结束信号:传感器的DATA引脚输出40位数据后,继续输出低电平54微秒后转为输入状态,由于上拉电阻随之变为高电平。但传感器内部重测环境温湿度数据,并记录数据,等待外部信号的到来。
数据解读
DHT11
DHT22
示例程序
DHT11_22.c
#include "DHT11_22.h"
void delay_ms(int i);
void delay_10us(uint8_t n);
DHT_data DHT_Data = {0};
void DHT_Read(DHT_data *dht_data)
{
uint8_t DHT_timeout_count, i, j;
uint8_t data_temp[6];
uint8_t DHT_Byte;
//主机拉低18~30ms
DHT_IO_L();
delay_ms(20);
DHT_IO_H();
//总线由上拉电阻拉高 主机延时50us
delay_10us(5);
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!DHT_IO_read())
{
//判断从机是否发出 80us 的低电平响应信号是否结束
DHT_timeout_count = 0;
while(!DHT_IO_read())
{
delay_10us(1);
if(++DHT_timeout_count >= 10)
return;
}
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
DHT_timeout_count = 0;
while(DHT_IO_read())
{
delay_10us(1);
if(++DHT_timeout_count >= 10)
return;
}
for(i = 0; i < 5; ++i)
{
for(j = 0, DHT_Byte = 0; j < 8; ++j)
{
DHT_Byte <<= 1;
DHT_timeout_count = 0;
while(!DHT_IO_read())
{
delay_10us(1);
if(++DHT_timeout_count >= 10)
{
DHT_Byte = 0;
break;
}
}
delay_10us(3); //跳过数据0的时间段,只检测数据为1时的电平
if(DHT_IO_read())
{
++DHT_Byte;
while(DHT_IO_read())
{
delay_10us(1);
if(++DHT_timeout_count >= 10)
{
DHT_Byte = 0;
break;
}
}
}
}
data_temp[i] = DHT_Byte;
}
for(i = 0, data_temp[5] = 0; i < 4; ++i)
data_temp[5] += data_temp[i];
if(data_temp[5] == data_temp[4]) //数据解读
{
#ifdef DHT11
dht_data->RH = data_temp[0] + (data_temp[1] & 0x0f)/10.;
dht_data->Temp = data_temp[2] + (data_temp[3] & 0x0f)/10.;
if(data_temp[3] & 0x80)
dht_data->Temp *= -1;
#endif
#ifdef DHT22
dht_data->RH = ((int16_t)data_temp[0] << 8 | data_temp[1])/10.;
dht_data->Temp = ((int16_t)(data_temp[2] & 0x7f) << 8 | data_temp[3])/10.;
if(data_temp[2] & 0x80)
dht_data->Temp *= -1;
#endif
}
}
}
DHT11_22.h
#ifndef DHT11_22_H
#define DHT11_22_H
#include #include #define DHT11 //#define DHT22 typedef struct { float RH; float Temp; } DHT_data; #define DHT_IO_H() {P00=1;} #define DHT_IO_L() {P00=0;} #define DHT_IO_read() P00 extern DHT_data DHT_Data; void DHT_Read(char *Str); #endif 测试程序 stdint.h见【51单片机快速入门指南】1:基础知识和工程创建 串口部分见【51单片机快速入门指南】3.3:USART 串口通信 定时器的介绍和配置源码见【51单片机快速入门指南】3.2:定时器/计数器 在头文件中选择使用的型号: main.c #include #include "intrins.h" #include "stdint.h" #include "USART.h" #include "TIM.h" #include "DHT11_22.h" void Delay1ms() //@22.1184MHz { unsigned char i, j; _nop_(); i = 4; j = 146; do { while (--j); } while (--i); } void delay_ms(int i) { while(i--) Delay1ms(); } uint8_t TIM0_Counter = 0; void delay_10us(uint8_t n) { TL0 = TH0; TIM0_Counter = n; while(TIM0_Counter > 1); } void main(void) { USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 22118400, 115200, DOUBLE_BAUD_ENABLE, USART_TIMER_1); Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400, 10, STC_TIM_Priority_Highest); //定时器配置为10us中断一次,8位重装载 delay_ms(1500); while(1) { DHT_Read(&DHT_Data); printf("%f %frn", DHT_Data.RH, DHT_Data.Temp); delay_ms(2000); } } 实验现象 DHT11 DHT22
上一篇:【51单片机快速入门指南】7:片上EEPROM
下一篇:【51单片机快速入门指南】6.3.1:使用1-WIRE搜索算法搜索单总线上所有DS18B20的ID
推荐阅读最新更新时间:2024-11-05 13:16
设计资源 培训 开发板 精华推荐
- 基于STF17N62K3功率MOSFET的后沿相位控制旋转壁调光器
- DAPLink-MM32F103
- 可充电无外壳款雕刻立牌嘉然向晚小夜灯
- LTC3204EDC-3.3 演示板,采用 2x2 DFN 的低噪声稳压充电泵,Vin = 1.8V-4.5V,Vout = 3.3V/(40-50mA 最大值)
- ZR431FTA 可调精密齐纳并联稳压器的典型应用
- LTC1700、2.5V 输入、3.3V/1.8A 输出稳压器
- LTC3440,转换器从 USB 或 PCMCIA 为 GSM 调制解调器供电
- #第七届立创电赛#基于N32G455示波器
- 典型应用显示使用 A8518 LED 驱动器的可选 P 沟道 MOSFET 进行 VOUT 接地短路保护
- LTC3624EMSE-3.3 3.3V 输出电压、2A 同步降压稳压器的典型应用,具有 800mA 突发钳位,fSW = 1MHz