STM32采集DHT11温湿度传感器的信号采集

发布者:人妙果华最新更新时间:2016-10-11 来源: eefocus关键字:STM32  DHT11  温湿度传感器  信号采集 手机看文章 扫描二维码
随时随地手机看文章
首先的介绍下DHT11这款温湿度传感器。
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。
DHT11温湿度传感器的引脚定义如下:

Pin

名称

注释

1

VDD

供电 3-5.5VDC

2

DATA

串行数据,单总线

3

NC

空脚,请悬空

4

GND

接地,电源负极

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:

一次完整的数据传输为40bit,高位先出。

数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和

数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

通讯过程如下:

1、用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。过程如图1所示:STM32采集DHT11温湿度传感器温湿度信号的程序解析 - ziye334 - ziye334的博客

图1

 

  总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。如图2所示:
 STM32采集DHT11温湿度传感器温湿度信号的程序解析 - ziye334 - ziye334的博客
图2

数字0信号表示方法如图3所示:

STM32采集DHT11温湿度传感器温湿度信号的程序解析 - ziye334 - ziye334的博客
图3
 

数字1信号表示方法.如图4所示:

STM32采集DHT11温湿度传感器温湿度信号的程序解析 - ziye334 - ziye334的博客

  图4

 

 

接下去得讲述下STM32实现的DHT11驱动。

首先,得建立个基于库开发的STM32的使用工程,这里就不详细说明。

由于单总线的时序要求,需要写两个精确的延时函数:Delay_nus()和Delay_nms()。代码如下(使用如下代码的前提是你已将系统时钟配置为9MHz,72MHz的8分频):


/********************************************************
函数:Delay_us()
描述:延时n个us
参数:无
返回:无
********************************************************/
void Delay_us(u32 nus)
{
SysTick->LOAD=nus*9; //时间加载
SysTick->CTRL|=0x01; //开始倒数
while(!(SysTick->CTRL&(1<<16)));//等待时间到达
SysTick->CTRL=0X00000000; //关闭计数器
SysTick->VAL=0X00000000; //清空计数器
}

/********************************************************
函数:Delay_ms()
描述:延时n个毫秒
参数:无
返回:无
********************************************************/
void Delay_ms(u16 nms)
{
SysTick->LOAD=(u32)nms*9000; //给重装载寄存器赋值,9000时,将产生1ms的时基
SysTick->CTRL|=0x01; //开始倒数
while(!(SysTick->CTRL&(1<<16))); //等待时间到达
SysTick->CTRL=0X00000000; //关闭计数器
SysTick->VAL=0X00000000; //清空计数器
}

接着新建DHT11.c 和DHT11.h两个文件,并添加到工程中。

DHT11.h文件主要是定义DHT11数据线的引脚定义及其一些引脚控制宏命令。代码如下:


#include "stm32f10x.h"
#include "BSP.h"
#include

//定义DHT11单总线的数据引脚,在这里宏定义,给移植带来了方便性
#define DHT11_PIN GPIO_Pin_5
#define DHT11_PORT GPIOA

//读取引脚输入的数据
#define DHT11_DATA_IN() GPIO_ReadInputDataBit(GPIOA,DHT11_PIN)

//控制引脚的高低电平
#define DHT11_DATA_OUT(a) if (a) \
GPIO_SetBits(DHT11_PORT,DHT11_PIN);\
else \
GPIO_ResetBits(DHT11_PORT,DHT11_PIN)

void DHT11Read(u8 RH , u8 RL , u8 TH , u8 TL);

#endif

 
 

DHT11.c这个文件主要实现如下几个函数:

void DHT11_GPIO_IN(void) ——设置GPIO口为输入模式

void DHT11_GPIO_OUT(void) ——设置GPIO口为输出状态

void DHT11WriteStart(void) ——发起开始信号

u8 DHT11ReadByte(void) ——从DHT11中读取一位数据

void DHT11Read(u8 RH , u8 RL , u8 TH , u8 TL) ——采样当前温湿度值
具体函数的实现及其详细的注解请参考下面的代码:


#include "DHT11.h"
/********************************************************
函数:DHT11_GPIO_IN
描述:设置GPIO口为输入状态
参数:无
返回:无
********************************************************/
void DHT11_GPIO_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置浮空输入
GPIO_Init(DHT11_PORT,&GPIO_InitStructure);
}

/********************************************************
函数:DHT11_GPIO_OUT
描述:设置GPIO口为输出状态
参数:无
返回:无
********************************************************/
void DHT11_GPIO_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置开漏输出
GPIO_Init(DHT11_PORT,&GPIO_InitStructure);
}

/********************************************************
函数:DHT11WriteStart
描述:发起开始信号
参数:无
返回:无
********************************************************/
void DHT11WriteStart(void)
{
DHT11_GPIO_OUT(); //设置io为输出模式
DHT11_DATA_OUT(1); //拉高
DHT11_DATA_OUT(0); //拉低
Delay_ms(18); //主机拉低总线必须大于18ms
DHT11_DATA_OUT(1); //拉高
Delay_us(30); //主机发送开始信号结束后延时等待20-40us
DHT11_GPIO_IN(); //启动信号开始后,为如数据将io设置设置为输入模式
}

/********************************************************
函数:DHT11ReadByte
描述:从DHT11中读取一位数据
参数:无
返回:返回读出来的数据
********************************************************/
u8 DHT11ReadByte(void)
{
u8 temp=0,i;
for(i=0;i<8;i++) //读取8位数据
{
while(DHT11_DATA_IN()==0);//等待变高电平
/*DHT11 以26us~28us的高电平表示“0”,以70us的高电平表示“1”
每一bit数据都以50us低电平时隙开始,当检测到60us后的电平区别状态*/
Delay_us(60);
if(DHT11_DATA_IN()==1) //60us后还是高电平则是“1”
{
while(DHT11_DATA_IN()==1);
temp|=(u8)(0x01<<(7-i));
}
else //否则是“0”
{
temp&=(u8)~(0x01<<(7-i));
}
}
return temp;
}

/********************************************************
函数:DHT11Read
描述:采样当前温湿度值
参数:
RH:湿度值的整数部分
RL: 湿度值的小数部分
TH: 温度值的整数部分
TL: 温度值的小数部分
返回:
********************************************************/
void DHT11Read(u8 RH , u8 RL , u8 TH , u8 TL)
{
u8 sum = 0;
DHT11WriteStart(); //发起开始信号
if(DHT11_DATA_IN()==0)
{
while(DHT11_DATA_IN()==0);
while(DHT11_DATA_IN()==1);
RH = DHT11ReadByte(); //湿度高8位
RL = DHT11ReadByte(); //湿度低8位
TH = DHT11ReadByte(); //温度高8位
TL = DHT11ReadByte(); //温度低8位
sum = DHT11ReadByte(); //校验和

DHT11_GPIO_OUT(); //采样结束后设置io口为输出,等待下一次开始信号
DHT11_DATA_OUT(1); //设置总线空闲状态为高电平
if(sum == RH+RL+TH+TL) //校验和与计算出的数据相等
{
printf("当前环境湿度为%d.%d﹪,当前环境温度为%d.%d℃\r\n",RH,RL,TH,TL);
}
else
{
printf("采样失败!!!\r\n");
}
}
}
 

注意:编写DHT11驱动的时,可能会出现很多的问题。问题主要有两部分:
1、DHT11的接触不好,导致程序执行不下去(代码中不是有很多的while()语句吗),代码没有任何现象,所以首先要确保接触良好。
2、DHT11读出来的数据不正确,这可能是由于时序编写不正确,比如说Delay_nus()和Delay_nms()两个延时函数,延时时间不正确,所以一定要首先保证延时函数精确延时,没有大的偏差。
关键字:STM32  DHT11  温湿度传感器  信号采集 引用地址:STM32采集DHT11温湿度传感器的信号采集

上一篇:移植到STM32fl13野火开发板上遇到的问题
下一篇:基于USB2.0接口的生物阻抗分析仪的研制

推荐阅读最新更新时间:2024-03-16 15:14

STM32学习笔记之IAR下建立FWlib 3.0项目
开发工具:JLink V7.0 开发环境:IAR5.3 第一步:下载函数库 从ST官方网站(http://www.st.com/stonline/products/support/micro/files/um0427.zip)下载STM32 V3.0固件函数库。 第二步:复制库文件 将下载的软硬件函数库解压后,将目录中的【Libraries】目录拷贝到您的项目目录中,然后【Project】目录下的【Template】目录下的main.c、stm32f10x_conf.h、stm32f10x_it.c、stm32f10x_it.h四个文件拷贝到您的目录下,然后将【Project】——【Template】——【EWARMv5
[单片机]
<font color='red'>STM32</font>学习笔记之IAR下建立FWlib 3.0项目
stm32驱动段式lcd液晶显示--非使用1621驱动芯片驱动
1.先说一下概念:(类似于数码管) LCD的驱动不像LED那样,加上电压(LED实际上是电流驱动)就可以长期显示的。 LCD驱动必须使用交流电压驱动才能保持稳定的显示,如果在LCD上加上稳定的直流电压,不但不能正常显示,时间久了还会损坏LCD。 一段LCD由背电极和段电极组成,需要显示时,在背电极和段电极之间加上合适的交流电压(通常使用方波)。 为了调节对比度,可以调节方波中每半个周期中显示的时间(即占空比)来实现 通常,为了节约驱动口,将多个背电极连在一起,形成公共背电极端:COM。 另外,再将属于不同COM的段电极连接在一起,形成公共段电极端:SEG。当在某个COM和某个SEG之间加了足够的交流电压之后,就会将对应的段点亮
[单片机]
基于STM32单片机的盆栽系统设计
一.系统设计 本次盆栽系统的设计使用STM32单片机作为控制中心,通过光敏模块检测光照强度,通过DHT11测量温湿度,通过土壤湿度传感器检测土壤湿度,检测到的数据通过LCD显示屏显示,当土壤湿度低于下限时,继电器控制灌溉,当土壤湿度高于上限时,继电器控制除湿,当温度低于阈值时,继电器控制加热,当光强低于阈值时,继电器控制补光。 图1 系统框图 二.硬件设计 本设计所采用的STM32F103C8T6是以Cortex-3为核心的单片机,它的功能是实现软件的执行,并对外部的器件、模块进行控制。该系统由LCD显示模块,温湿度检测模块,光敏电阻模块,湿度检测模块,继电器模块组成。 图2 硬件电路 三.软件设计 系统的软件实现过程中首
[单片机]
基于<font color='red'>STM32</font>单片机的盆栽系统设计
STM32学习记录10:存储器结构
一直以来对存储器的结构都十分的模糊,初学单片机是完全看不懂,以至于有心理阴影,今天彻底消灭他吧!! 存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。 1:CM3存储器映射 如图,是Cortex-M3存储器映射结构图摘自《CM3技术手册》。 Cortex-M3是32位的内核,因此其PC指针可以指向2^32=4G的地址空间,也就是0x0000_0000 0xFFFF_FFFF这一大块空间。 好,根据图中描述,Cortex-M3内核将0x0000_0
[单片机]
<font color='red'>STM32</font>学习记录10:存储器结构
STM32 双DAC DMA TIM6输出正弦波例子
STM32F103有双DAC通道,利用DMA实现2个波形输出 #include stm32f10x.h //DAC1,2初始化 void dac_init(void) { RCC- APB2ENR |= RCC_APB2ENR_IOPAEN; //开启端口A时钟 RCC- APB1ENR |= RCC_APB1ENR_DACEN; //开启DAC时钟 GPIOA- CRL &= 0xff00ffff; //PA4,PA5模拟输入 DAC- CR = DAC_CR_TEN1 | DAC_CR_TEN2; //开启触发使能才能设置触发模式 //开启DAC,关闭输出缓存,TI
[单片机]
STM32之寄存器开发
首先克服心理作用,不要总是默认寄存器开发难,其实寄存器开发和库函数开发所用的方法和难度是一样的, 并不难,下面用以stm32为例解释。 : 1.明确自己需要的功能(库函数开发也需要) 2.查看手册,找到功能对应的单片机资源 3.找到功能所需寄存器(库函数开发需要找到相应的功能函数) 4.根据地址每位对应的功能赋值(库函数开发需要找到相应的入口函数) 5.调试结束。 而且寄存器开发不难但是麻烦,有很多没接触过的名词(有可能是一些英文缩写),所以需要耐心,慢慢品味。如果这些名词弄清楚了,寄存器开发反而会比库函数开发简单、方便。 注:名词或需要整理的步骤太多可以手动记一下,既有利于理清思路,也方便回看时
[单片机]
stm32启动文件ld md hd cl vl xl分析及选择
说的直白点就是以下区别,在选择启动文件的时候有选择性区别! startup_stm32f10x_cl.s 互联型的STM32F105xx,STM32F107xx startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_hd_vl.s 大容量的STM32F100xx startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_ld_vl.s 小容量的STM32F100xx startup_stm32f10x_md.s 中容量的S
[单片机]
<font color='red'>stm32</font>启动文件ld md hd cl vl xl分析及选择
STM32单片机中断详解
中断,在单片机中占有非常重要的地位。代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转。而在单片机执行代码的过程中,难免会有一些突发的情况需要处理,这样就会打断当前的代码,待处理完突发情况之后,程序会回到被打断的地方继续执行。 1 EXTI控制器 外部中断/事件控制器(EXTI)管理了控制器的 23 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。 外部信号进入经过1的边沿检测电路,检测是否符合(有2和3的上升沿和下降沿选择寄存器决定),产生信号,然后和4软件
[单片机]
<font color='red'>STM32</font>单片机中断详解
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved