DHT11温湿度传感器
DHT1 1数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传 感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高 的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测 温元件。
传感器性能:
接线方式
DHT11 VCC接 3.3V,DATA接stm32的A0引脚,GND接GND
数据的读取(单总线)
MCU与 DHT1 1之间的通讯和同步,采用单总线数据格式,一次 通讯时间 4ms左右,数据分小数部分和整数部分,具体格式在下面说明 ,当前小数 部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输为40bi t,高位先出。 数据格式: 8bi t湿度整数数据+8bi t湿度小数数据 +8bi温度整数数据+8bi t温度小数数据 +8bi t校验和 数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据”所得结果的末8位。 用户 MCU发送一次开始信号后, DHT1 1从低功耗模式转换到高速模式,等待主 机开始信号结束后, DHT1 1发送响应信号,送出 40bi t的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下, DHT1 1接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号, DHT1 1不会主动进行温湿度采集.采集数据后 转换到低速模式。
代码
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "DHT11.h"
DHT11_Data_TypeDef DHT11_Data;
int main(void)
{
OLED_Init();
DHT11_GPIO_Config();
Serial_Init();
while (1)
{
if(Read_DHT11(&DHT11_Data) == SUCCESS)
{
printf("humi:=%d.%d",DHT11_Data.humi_int,DHT11_Data.humi_deci);
printf("temp:=%d.%d\r\n",DHT11_Data.temp_int,DHT11_Data.temp_deci);
Delay_ms(500);
}
}
}
DHT11.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "DHT11.h"
void DHT11_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(DHT11_Out_RCC, ENABLE);
GPIO_InitStructure.GPIO_Pin = DHT11_Out_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11, &GPIO_InitStructure);
GPIO_SetBits(DHT11, DHT11_Out_Pin);
}
static void DHT11_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_Out_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
GPIO_Init(DHT11, &GPIO_InitStructure);
}
static void DHT11_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DHT11_Out_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11, &GPIO_InitStructure);
}
static uint8_t Read_Byte(void)
{
uint8_t i, temp=0;
for (i=0; i<8; i++)
{
while (DHT11_DATA_IN() == Bit_RESET);
Delay_us(40);
if (DHT11_DATA_IN() == Bit_SET)
{
while(DHT11_DATA_IN() == Bit_SET);
temp |= (uint8_t)(0x01 << (7 - i));
}
else
{
temp &= (uint8_t) ~ (0x01<<(7-i));
}
}
return temp;
}
uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
{
DHT11_Mode_Out_PP();
DHT11_DATA_OUT(LOW);
Delay_ms(18);
DHT11_DATA_OUT(HIGH);
Delay_us(30);
DHT11_Mode_IPU();
if(DHT11_DATA_IN() == Bit_RESET)
{
while(DHT11_DATA_IN() == Bit_RESET);
while(DHT11_DATA_IN() == Bit_SET);
DHT11_Data -> humi_int = Read_Byte();
DHT11_Data -> humi_deci = Read_Byte();
DHT11_Data -> temp_int = Read_Byte();
DHT11_Data -> temp_deci = Read_Byte();
DHT11_Data -> check_sum= Read_Byte();
DHT11_Mode_Out_PP();
DHT11_DATA_OUT(HIGH);
if (DHT11_Data -> check_sum == DHT11_Data -> humi_int + DHT11_Data -> humi_deci + DHT11_Data -> temp_int + DHT11_Data -> temp_deci)
return SUCCESS;
else
return ERROR;
}
else
{
return ERROR;
}
}
Serial.c
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1, Byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
uint16_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Array[i]);
}
}
void Serial_SendString(char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)
{
Serial_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result = 1;
while (Y --)
{
Result *= X;
}
return Result;
}
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
}
}
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch);
return ch;
}
void Serial_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg);
va_end(arg);
Serial_SendString(String);
}
实测效果
结语
上述代码,均经过实测验证。
本文所有内容均为原创,如需转载请附上本文网址。
如果需要相关代码等资料可以私聊我。