stm32F4使用温湿度传感器模块-->DHT11
程序员文章站
2022-07-13 17:15:36
...
我终于弄出来了,温湿度传感模块
就是 雁凌家的模块,测好了,弄了很久吧发现是他们家的杜邦线不行,以后买模块要看杜邦线质量,还是买点好的
太耽误开发周期了
我们用的模块是四线 转三线的(dht11从四线的引脚变成三线的输出)
线路连接
dht11 有三根线连出来,vcc,gnd,还有一个负责输入和输出
所以最后一根线可以连接到没有被占用的gpio口就能获得数据
连接到板子的 pb2上面
程序编写
唤醒dht11 ->检测dht11是否存在 -> 读取数据
唤醒dht11
输出低电平 20ms 再输出 高电平 30us
//复位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //设置为输出
DHT11_DQ_OUT=0; //拉低DQ
delay_ms(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
delay_us(30); //主机拉高20~40us
}
检测dht11
唤醒后dht11 会拉低电频40,80us 拉低后会再次拉高40~80us
读取数据
读取一位数据
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;
}
读取一个byte数据
就是循环读取八个位
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;
}
对所有数据进行拼装,得到温度值
从总共的40byte里拿出我们的数据,小数部分就不要了,好像是不支持
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.c
#include "dht11.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//DHT11驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/16
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//复位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //设置为输出
DHT11_DQ_OUT=0; //拉低DQ
delay_ms(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
delay_us(30); //主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN(); //设置为输入
while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_DQ_IN&&retry<100)//等待变为低电平
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT11_DQ_IN&&retry<100)//等待变高电平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(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的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
u8 DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
GPIO_Initure.Pin=GPIO_PIN_2; //PB12
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化
DHT11_Rst();
return DHT11_Check();
}
dht11.h
#ifndef __DS18B20_H
#define __DS18B20_H
#include "sys.h"
//IO方向设置
#define DHT11_IO_IN() {GPIOB->MODER&=~(3<<(2*2));GPIOB->MODER|=0<<(2*2);} //PB12输入模式
#define DHT11_IO_OUT() {GPIOB->MODER&=~(3<<(2*2));GPIOB->MODER|=1<<(2*2);} //PB12输出模式
////IO操作函数
#define DHT11_DQ_OUT PBout(2)//数据端口 PB12
#define DHT11_DQ_IN PBin(2) //数据端口 PB12
u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11
#endif
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "sdram.h"
#include "dht11.h"
#include "pcf8574.h"
int main(void)
{
u8 t=0;
u8 temperature;
u8 humidity;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //初始化LCD
PCF8574_Init(); //初始化PCF8574
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");
LCD_ShowString(30,70,200,16,16,"DHT11 TEST");
LCD_ShowString(30,90,200,16,16,"aaa@qq.com");
LCD_ShowString(30,110,200,16,16,"2016/1/16");
PCF8574_ReadBit(BEEP_IO); //由于DHT11和PCF8574的中断引脚共用一个IO,
//所以在初始化DHT11之前要先读取一次PCF8574的任意一个IO,
//使其释放掉中断引脚所占用的IO(PB12引脚),否则初始化DS18B20会出问题
while(DHT11_Init()) //DHT11初始化
{
LCD_ShowString(30,130,200,16,16,"DHT11 Error");
delay_ms(200);
LCD_Fill(30,130,239,130+16,WHITE);
delay_ms(200);
}
LCD_ShowString(30,130,200,16,16,"DHT11 OK");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,150,200,16,16,"Temp: C");
LCD_ShowString(30,170,200,16,16,"Humi: %");
while(1)
{
if(t%10==0)//每100ms读取一次
{
PCF8574_ReadBit(BEEP_IO); //读取一次PCF8574的任意一个IO,使其释放掉PB12引脚,
//否则读取DHT11可能会出问题
DHT11_Read_Data(&temperature,&humidity); //读取温湿度值
LCD_ShowNum(30+40,150,temperature,2,16); //显示温度
LCD_ShowNum(30+40,170,humidity,2,16); //显示湿度
}
delay_ms(10);
t++;
if(t==20)
{
t=0;
LED0=!LED0;
}
}
}
上一篇: Git使用中遇到的问题
下一篇: DHT11型温湿度传感器的使用(附源码)