#申请原创#
本次测试计划是尝试做一个多功能时钟,显示当前的温湿度是其中的一项辅助功能,传感器就选用最常见的DHT11,尽管这款传感器的测量范围和精度都有限,但对于家庭使用来说还是绰绰有余的。下图是传感器的介绍资料:
这是一些基本的指标:
这是传感器的性能指标:
这款传感器是单总线数据传输方式,收到主机发出的启动信号后,返回4字节的温温度数据和1字节的校验码:
下面是数据信号的时序要求:
通过高电平持续时间的长短来确定数字0或数字1:
这是封装信息:
传感器的驱动代码借鉴了dql2015大侠的帖子(https://bbs.21ic.com/icview-3119748-1-1.html),下面是测试过程的照片,测试时与我的另一块温湿度传感器评估板进行了比较,差别不大,作为家庭使用精度是绰绰有余的。
下面是我用逻辑分析仪抓取的数据时序图,当主机发出大于20ms的低电平信号后再拉高约20us,传感器便发回测量数据:
这是测量数据的分析:
下面的动画是我用电吹风进行测试,当用电吹风加热传感器时,测得的湿度数值会降低,而温度数值则会增大:
这是DHT11的驱动代码,我是直接通过全局变量数组来传递数据的:
#include "dht.h"
#include "lcd_19264.h"
extern uint8_t DHT[5];
/*********************************************
* 函数名称:DHT11_Rst()
* 函数功能:温湿度传感器复位
* 入口参数:无
* 出口参数:无
* 备注:工作电压 :3.3V ~ 5.5 V
*********************************************/
void DHT11_Rst(void)
{
DHT11_SetDigitalOutput();
DHT11_SetLow(); //拉低DQ
delay_ms(25); //拉低至少18ms
DHT11_SetHigh(); //DQ=1
delay_us(30); //主机拉高20~40us
}
/*********************************************
* 函数名称:DHT11_Check()
* 函数功能:等待传感器回应
* 入口参数:无
* 出口参数:返回1: 未检测到DHT11的存在
* 返回0: 存在
*********************************************/
uint8_t DHT11_Check(void)
{
uint8_t retry=100;
DHT11_SetDigitalInput();
DHT11_SetPullUp();
while ((DHT11_GetValue())&&retry) //DHT11会拉低40~80us
{
retry--;
delay_us(1);
};
if(retry<1) return 1;
else retry=100;
while (!DHT11_GetValue()&&retry) //DHT11拉低后会再次拉高40~80us
{
retry--;
delay_us(1);
};
if(retry<1)
return 1;
return 0;
}
/*********************************************
* 函数名称:DHT11_Read_Val()
* 函数功能:读取温湿度传感器数据
* 入口参数:无
* 出口参数:无
* 备注:数据存放在全局变量DHT中,DHT[0]=湿度整数部分,DHT[1]=湿度小数部分,DHT[2]=温度整数部分,DHT[3]=温度小数部分,
* 湿度值(范围:20% RH ~ 90% RH 分辨率:0.1%RH 精度:±5% RH (25℃))
* 温度值(范围:0℃ ~ 50℃ 分辨率:0.1℃ 精度:±2)
*********************************************/
void DHT11_Read_Val(void)
{
uint8_t dat,retry,i,j;
DHT11_Rst();
if(DHT11_Check()==0){
for(i=0; i<5; i++)
{
DHT[i]=DHT11_Read_Byte(); //调用读取字节的函数
}
if(DHT[4]==DHT[0]+DHT[1]+DHT[2]+DHT[3])
DHT[4] = 0;
else
DHT[4] = 1;
}
}
/*********************************************
* 函数名称:DHT11_Read_Byte()
* 函数功能:读取单总线一个字节数据
* 入口参数:无
* 出口参数:读取的字节
*********************************************/
uint8_t DHT11_Read_Byte(void)
{
uint8_t i,dat,retry;
dat=0;
for (i=0;i<8;i++)
{
retry = 100;
while((DHT11_GetValue())&&retry)//等待变为高电平
{
retry--;
delay_us(1);
}
retry=100;
while(!DHT11_GetValue()&&retry)//等待变低电平
{
retry--;
delay_us(1);
}
delay_us(40);//wait 40us
dat<<=1;
if(DHT11_GetValue())
dat|=0x01;
}
return dat;
}
/*********************************************
* 函数名称:DHT11_Init()
* 函数功能:温湿度传感器初始化
* 入口参数:无
* 出口参数:0 = 初始化成功
* 1 = 初始化失败
*********************************************/
uint8_t DHT11_Init(void)
{
DHT11_SetDigitalOutput();
DHT11_SetHigh();
DHT11_Rst();
return DHT11_Check();
}
在测试时发现一个问题:我将读取一个字节的函数代码合并在读取数值函数中,读取的数值便会出错,非得独立出一个函数,然后再去调用,才能读取正确的数据,反复测试多次均是如此,具体原因尚不清楚。
|