本帖最后由 dql2015 于 2021-3-27 11:04 编辑
#申请原创#
DHT22(AM2302)是已校准的数字温湿度传感器,用于检测环境温湿度,标准单总线接口,拥有比DHT11更高的精度和更大的量程。DHT22湿敏电容数字温湿度模块是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。主要技术指标如下:温度分辨率:0.1°C
精度:±0.5℃
检测范围:-40°C ~ 80°C
湿度
分辨率:0.1%RH
精度:±2%RH (25°C)
检测范围:0%RH ~ 99.9%RH
工作电压 :3.3V ~ 5.5 V
通信时序:
这里采用MCC快速配置一个IO PB4来驱动DHT22。
驱动头文件dht.h
#ifndef DHT_H
#define DHT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mcc_generated_files/mcc.h"
#define delay_ms(d) DELAY_milliseconds(d)
#define delay_us(d) DELAY_microseconds(d)
#define u8 uint8_t
#define u16 uint16_t
u8 DHT22_Init(void);
u8 DHT22_Read_Data(u16 *temperature,u16 *humidity);
u8 DHT22_Read_Byte(void);
u8 DHT22_Read_Bit(void);
u8 DHT22_Check(void);
void DHT22_Rst(void);
#ifdef __cplusplus
}
#endif
#endif /* DHT_H */
驱动源文件dht.c
#include "dht.h"
//工作电压 :3.3V ~ 5.5 V
//复位DHT22
void DHT22_Rst(void)
{
DHT22_SetDigitalOutput();
DHT22_SetLow(); //拉低DQ
delay_ms(30); //拉低至少18ms
DHT22_SetHigh(); //DQ=1
delay_us(30); //主机拉高20~40us
}
//等待DHT22的回应
//返回1:未检测到DHT22的存在
//返回0:存在
u8 DHT22_Check(void)
{
u8 retry=100;
DHT22_SetDigitalInput();
DHT22_SetPullUp();
while ((DHT22_GetValue())&&retry)//DHT22会拉低40~80us
{
retry--;
delay_us(1);
};
if(retry<1) return 1;
else retry=100;
while (!DHT22_GetValue()&&retry)//DHT22拉低后会再次拉高40~80us
{
retry--;
delay_us(1);
};
if(retry<1)
return 1;
return 0;
}
//从DHT22读取一个位
//返回值:1/0
u8 DHT22_Read_Bit(void)
{
u8 dat=0;
u8 retry=100;
while((DHT22_GetValue())&&retry)//等待变为高电平
{
retry--;
delay_us(1);
}
retry=100;
while(!DHT22_GetValue()&&retry)//等待变低电平
{
retry--;
delay_us(1);
}
delay_us(40);//wait 40us
if(DHT22_GetValue())
dat=1;
else
dat=0;
return dat;
}
//从DHT22读取一个字节
//返回值:读到的数据
u8 DHT22_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT22_Read_Bit();
}
return dat;
}
//从DHT22读取一次数据
//temp:温度值(范围:-40°C ~ 80°C 分辨率:0.1°C 精度:±0.5℃)
//humi:湿度值(范围:0%RH ~ 99.9%RH 分辨率:0.1%RH 精度:±2%RH (25°C))
//返回值:0,正常;1,读取失败
u8 DHT22_Read_Data(u16 *temperature,u16 *humidity)
{
u8 buf[5];
u8 i;
u8 sum;
*humidity=0;
*temperature=0;
DHT22_Rst();
if(DHT22_Check()==0)
{
for(i=0;i<5;i++)
{
buf[i]=DHT22_Read_Byte();
}
sum = buf[0]+buf[1]+buf[2]+buf[3];
if(sum == buf[4])
{
*humidity=(u16)((buf[0]<<8)+buf[1]);
*temperature=(u16)((buf[2]<<8)+buf[3]);
}
else
{
*humidity=(u16)((buf[0]<<8)+buf[1]);
*temperature=(u16)((buf[2]<<8)+buf[3]);
}
}
else
{
return 1;
}
return 0;
}
//初始化DHT22同时检测DHT22的存在
//返回1:不存在
//返回0:存在
u8 DHT22_Init(void)
{
DHT22_SetDigitalOutput();
DHT22_SetHigh();
DHT22_Rst();
return DHT22_Check();
}
主机从DHT22读取的温湿度数据总是前一次的测量值,如两次测量间隔时间很长,连续读两次以第二次
获得的值为实时温湿度值,建议同时两次读取间隔时间最小为 2S。
主函数进行初始化,定时读取DHT温湿度并打印,由于CuriosityNano的printf函数不支持打印小数,因此这里的温湿度值是实际值*10。
#include "mcc_generated_files/mcc.h"
#include "dht.h"
void KeyInterruptHandler(void)
{
LED_Toggle();
}
int main(void)
{
SYSTEM_Initialize();
PB0_SetDigitalOutput();
//PB1_SetDigitalInput();
LED_SetDigitalOutput();
LED_SetHigh();
KEY_SetPullUp();
PORTB_KEY_SetInterruptHandler(KeyInterruptHandler);
printf("AVR128DB48 Curiosity Nano DHT22 Test,by dql2015[url=home.php?mod=space&uid=31587]@21IC[/url] 2021-03-27\r\n");
DELAY_milliseconds(3000);
while(DHT22_Init())
{
printf("no dht22\r\n");
DELAY_milliseconds(500);
}
u16 t,h;
while (1)
{
DHT22_Read_Data(&t,&h);
printf("Temp:%d Hum:%d\r\n", t, h);
DELAY_milliseconds(1000);
}
}
实物接线图:
实验结果:
测试工程源码:
test.X.rar
(154.2 KB)
|