最近使用msp430f5529读取dht11的温度和湿度数据,记录下驱动程序,需要可移植。
dht11模块是一块温湿度传感器模块,可以采集温度和湿度信息转化为数据发送出来,模块介绍如下:
概述:DHT11 是广州奥松有限公司生产的一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。
- 性能参数
工作电压范围:3.5V-5.5V
工作电流 :平均 0.5mA
湿度测量范围:20-90%RH
温度测量范围:0-50℃
湿度分辨率 :1%RH 8 位
温度分辨率 :1℃ 8 位
采样周期 :1S
单总线结构
与 TTL 兼容(5V)
典型应用电路
串行接口
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式 : 8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通讯过程:
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必
须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后, 等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束
后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换
到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉
高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定
了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有
响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线
50us,随后总线由上拉电阻拉高进入空闲状态。
信号表示方法:
驱动程序:
头文件:
/*
* dht11.h
*
* Created on: 2019年7月10日
* Author: 23605
*/
#ifndef DHT11_H_
#define DHT11_H_
#define DHT_Direction_IN {P3DIR &= ~BIT3;P3REN |= BIT3;P3OUT |= BIT3;}
#define DHT_Direction_OUT P3DIR |= BIT3;
#define O_DHT_DAT_H P3OUT |= BIT3
#define O_DHT_DAT_L P3OUT &= ~BIT3
#define I_DHT_DAT (P3IN & BIT3)
void delay_ms(uint16_t ms);
void delay_us(uint32_t us);
void DHT11_Reset(void);
uint8_t DHT11_IsOnline(void);
uint8_t DHT11_ReadBit(void);
uint8_t DHT11_ReadByte(void);
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *temps,uint8_t *humi);
void DHT11_INIT(void);
#endif /* DHT11_H_ */
源文件:
/*
* dht11.c
*
* Created on: 2019年7月10日
* Author: 23605
*/
#include <msp430.h>
#include "LCD.h"
#include "hal_ucs.h"
#include "hal_pmm.h"
#include "ff.h"
#include "SHT20.h"
#include "IIC.h"
#include "dht11.h"
#include <stdio.h>
#define SYSCLK 25000000/1000 //_delay_cycles(SYSCLK) [系统时钟/1000] 1ms'Ticks
#define SYSCLK2 25
void delay_ms(uint16_t ms)
{
uint16_t k;
for(k=0;k<ms;k++)
_delay_cycles(SYSCLK); // 25000即当前时钟设在25MHz
}
void delay_us(uint32_t us)
{
uint32_t k;
for(k=0;k<us;k++)
_delay_cycles(SYSCLK2); // 25即当前时钟设在25MHz
}
//复位DHT11
void DHT11_Reset(void)
{
DHT_Direction_OUT;
O_DHT_DAT_L;
delay_ms(20);
O_DHT_DAT_H;
delay_us(30);
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_IsOnline(void)
{
uint8_t retry = 0;
DHT_Direction_IN;
while (I_DHT_DAT && retry < 100)//DHT11会拉低40~80us
{
retry ++;
delay_us(1);
}
if(retry >= 100)
{
return 1;
}
else
{
retry = 0;
}
while (!I_DHT_DAT && retry < 100)//DHT11拉低后会再次拉高40~80us
{
retry ++;
delay_us(1);
}
if(retry >= 100)
{
return 1;
}
return 0;
}
uint8_t DHT11_ReadBit(void)
{
uint8_t retry = 0;
while(I_DHT_DAT && retry < 100)
{
retry ++;
delay_us(1);
}
retry = 0;
while(!I_DHT_DAT && retry < 100)
{
retry ++;
delay_us(1);
}
delay_us(40);//等待40us
if(I_DHT_DAT)
{
return 1;
}
else
{
return 0;
}
}
uint8_t DHT11_ReadByte(void)
{
uint8_t i,dat;
dat = 0;
for (i = 0; i < 8; i ++)
{
dat <<= 1;
dat |= DHT11_ReadBit();
}
return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *temps,uint8_t *humi)
{
uint8_t buf[5];
uint8_t i;
DHT11_Reset();
if(DHT11_IsOnline() == 0)
{
for(i = 0; i < 5; i ++)//读取40位数据
{
buf[i] = DHT11_ReadByte();
}
if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
{
*humi = buf[0]-2;
*temp = buf[2]-3;
*temps = buf[3];
}
}
else
{
return 1;
}
return 0;
}
void DHT11_INIT(void)
{
P3DIR |= BIT3;
P3OUT |= BIT3;
DHT11_Reset();
}