700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 基于STM32的DHT11温湿度传感器设计

基于STM32的DHT11温湿度传感器设计

时间:2020-06-10 19:28:19

相关推荐

基于STM32的DHT11温湿度传感器设计

文章目录

前言一、DHT11温湿度传感器是什么?二、DHT11驱动程序详解1.相关宏定义2.输入输出GPIO配置2.GPIO初始化设计3.检测DHT11是否正常工作4.读取DHT11数据5.显示温湿度数据三、DHT11驱动源码总结

前言

DHT11作为一款低价、入门级的温湿度传感器,常用于我们的单片机设计实例中;它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。

DHT11为 4 针单排引脚封装,如下图,采用单线制串行接口,只需加适当的上拉电阻,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选择。

一、DHT11温湿度传感器是什么?

详见:物联网外设学习笔记-数字温湿度传感器

二、DHT11驱动程序详解

1.相关宏定义

由上可知DHT11温湿度传感器接入STM32,GPIOG,11引脚,如下图所示。

2.输入输出GPIO配置

代码如下

2.GPIO初始化设计

总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后,读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高

代码如下

3.检测DHT11是否正常工作

检查DHT11是否正常,正常的话会在单片机发送起始信号完成后,传感器返回80us低电平,然后发送80us高电平。即证明DHT11工作正常,该函数工作正常返回0,否则返回1,该函数中利用了while循环检测在一定时间内的电平变化,此类用法在后面也会经常用到。

4.读取DHT11数据

数据格式:

8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和读取数据将数据存入数组,这里仅保留了温度数据的整数位,注意数据较验方法,校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

5.显示温湿度数据

数据处理函数

温湿度显示测试

三、DHT11驱动源码

头文件

#ifndef _dht11_H#define _dht11_H#include "system.h"#include "SysTick.h"#define DHT11 (GPIO_Pin_11) //PG11#define GPIO_DHT11 GPIOG#define DHT11_DQ_IN PGin(11) //输入#define DHT11_DQ_OUT PGout(11) //输出void DHT11_IO_OUT(void);void DHT11_IO_IN(void);u8 DHT11_Init(void);void DHT11_Rst(void);u8 DHT11_Check(void);u8 DHT11_Read_Bit(void);u8 DHT11_Read_Byte(void);u8 DHT11_Read_Data(u8 *temp,u8 *humi);#endif

源文件

#include "dht11.h"//DHT11初始化//返回0:初始化成功,1:失败u8 DHT11_Init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);GPIO_InitStructure.GPIO_Pin=DHT11;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);GPIO_SetBits(GPIO_DHT11,DHT11); //拉高DHT11_Rst();return DHT11_Check();}//复位DHT11void DHT11_Rst(){DHT11_IO_OUT(); //SET OUTPUTDHT11_DQ_OUT=0; //拉低DQdelay_ms(20); //拉低至少18msDHT11_DQ_OUT=1; //DQ=1delay_us(30);//主机拉高20~40us}//等待DHT11的回应//返回1:未检测到DHT11的存在//返回0:存在u8 DHT11_Check(){u8 retry=0;DHT11_IO_IN();//SET INPUTwhile (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~50us{retry++;delay_us(1);};if(retry>=100)return 1;else retry=0;while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~50us{retry++;delay_us(1);};if(retry>=100)return 1;return 0;}//从DHT11读取一个位//返回值:1/0u8 DHT11_Read_Bit(void){u8 retry=0;while(DHT11_DQ_IN&&retry<100)//等待变为低电平 12-14us 开始{retry++;delay_us(1);}retry=0;while(!DHT11_DQ_IN&&retry<100)//等待变高电平 26-28us表示0,116-118us表示1{retry++;delay_us(1);}delay_us(40);//等待40usif(DHT11_DQ_IN)return 1;else return 0;}//从DHT11读取一个字节//返回值:读到的数据u8 DHT11_Read_Byte(void){u8 i,dat;dat=0;for (i=0; i<8; i++){dat<<=1;dat|=DHT11_Read_Bit();}return dat;}//从DHT11读取一次数据//temp:温度值(范围:0~50°)//humi:湿度值(范围:20%~90%)//返回值:0,正常;1,读取失败u8 DHT11_Read_Data(u8 *temp,u8 *humi){u8 buf[5];u8 i;DHT11_Rst();if(DHT11_Check()==0){for(i=0; i<5; i++) //读取40位数据{buf[i]=DHT11_Read_Byte();}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humi=buf[0];*temp=buf[2];}} else return 1;return 0;}//DHT11输出模式配置void DHT11_IO_OUT(){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=DHT11;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);}//DHT11输入模式配置void DHT11_IO_IN(){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=DHT11;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入模式GPIO_Init(GPIO_DHT11,&GPIO_InitStructure);}

测试函数

#include "system.h"#include "SysTick.h"#include "led.h"#include "usart.h"#include "tftlcd.h"#include "dht11.h"void data_pros()//数据处理函数{u8 temp;u8 humi;u8 temp_buf[3],humi_buf[3];DHT11_Read_Data(&temp,&humi);temp_buf[0]=temp/10+0x30;temp_buf[1]=temp%10+0x30;temp_buf[2]='\0';LCD_ShowString(80,100,tftlcd_data.width,tftlcd_data.height,16,temp_buf);humi_buf[0]=humi/10+0x30;humi_buf[1]=humi%10+0x30;humi_buf[2]='\0';LCD_ShowString(80,130,tftlcd_data.width,tftlcd_data.height,16,humi_buf);}int main(){u8 i=0;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组LED_Init();//USART1_Init(9600);TFTLCD_Init();//LCD初始化LCD_Printf("Temp: C",10,100,24,2,WHITE,BLACK);LCD_Printf("Humi: %RH",10,130,24,2,WHITE,BLACK);while(DHT11_Init())//检测DHT11是否纯在{LCD_Printf("DHT11 Init Error",30,50,24,2,WHITE,BLACK);delay_ms(500);}LCD_Printf("DHT11 Init Success",30,50,24,2,WHITE,BLACK);while(1){i++;if(i%20==0){led1=!led1;data_pros(); //读取一次DHT11数据最少要大于100ms}delay_ms(10);}}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了DHT11温湿度传感器,及STM32版本驱动函数的编写

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。