DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,应用领域:暖通空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制
特点:
- 相对湿度和温度测量
- 全部校准,数字输出
- 长期稳定性
- 超长的信号传输距离:20米
- 超低能耗:休眠
- 4 引脚安装:可以买封装好的
- 完全互换 : 直接出结果,不用转化
数据传送逻辑
只有一根数据线DATA,单片机发送序列指令给DHT11模块,模块一次完整的数据传输为40bit,高位先出
数据格式
8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
通讯过程时序图
根据如下时序图,做通信初始化,并检测模块是否存在,功能是否正常
就是检测主机拉高后,DHT11是否在40us之后把时序拉低了
DHT11Start
void DHT11_Start()
{
dht = 1;
dht = 0;
Delay20ms();
dht = 1;
while(dht);
while(!dht);
while(dht);
}
DHT11传输0的时序分析
DHT11传输1的时序分析
数据是0或者1是看高电平的时长,持续高电平26—28us为1,70us为0,所以在40微妙的时候读dht电平来判断
C51实验:获取温湿度数据发送到串口
#include "reg52.h"
#include "intrins.h"
sfr AUXR = 0x8E;
sbit dht = P2^0;
sbit led = P2^1;
char datas[5];
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 10;
j = 183;
do
{
while (--j);
} while (--i);
}
void UartInit(void) //2400bps@12.000MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xF3; //设定定时初值
TH1 = 0xF3; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void sendByte(char data_byte)
{
SBUF = data_byte;
Delay5ms();
while(!TI);
TI = 0;
}
void sendString(char *str)
{
while(*str != '\0'){
sendByte(*str);
str++; //指针每发送一个字符就往后走,遇到\0的跳出循环
}
}
void Delay1000ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 154;
k = 122;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay20ms() //@12.000MHz
{
unsigned char i, j;
i = 39;
j = 230;
do
{
while (--j);
} while (--i);
}
void Delay40us() //@12.000MHz
{
unsigned char i;
_nop_();
i = 17;
while (--i);
}
void DHT11_Start()
{
dht = 1;
dht = 0;
Delay20ms();
dht = 1;
while(dht);
while(!dht);
while(dht);
}
void Read_Data_From_DTH11()
{
int i,j;
char tmp;
char flag;
DHT11_Start();
for(i=0;i<5;i++){
for(j=0;j<8;j++){
while(!dht);
Delay40us();//如果40us后读,读高电平就是代表1,读到低电平就是0
if(dht == 1){
flag = 1;
while(dht);
}else {
flag = 0;
}
tmp = tmp << 1;
tmp |= flag;
}
datas[i] = tmp;
}
}
void Show_DataToUart()
{
char hum[8];
char temp[8];
hum[0] = 'H';
hum[1] = ':';
hum[2] = datas[0]/10 + 0x30;
hum[3] = datas[0]%10 + 0x30;
hum[4] = '.';
hum[5] = datas[1]/10 + 0x30;
hum[6] = datas[1]%10 + 0x30;
hum[7] = '%';
temp[0] = 'T';
temp[1] = ':';
temp[2] = datas[2]/10 + 0x30;
temp[3] = datas[2]%10 + 0x30;
temp[4] = '.';
temp[5] = datas[3]/10 + 0x30;
temp[6] = datas[3]%10 + 0x30;
temp[7] = 'C';
Delay1000ms();
sendString(hum);
sendString("\r\n");
sendString(temp);
sendString("\r\n");
}
int main()
{
UartInit();//配置串口的通信方式
while(1){
Read_Data_From_DTH11();
Show_DataToUart();
}
return 0;
}
STM32:重复上面实验
使用CubeMX
注意:PB7既作为输入,也作为输出,则不能直接在CubeMX里配置,需要自己写代码
引脚封装
#define dht_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)
#define dht_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
#define read_dht HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)
#define dht_HIGH HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)
#define dht_LOW HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
#define read_dht HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)
/*
GPIO_MODE_INPUT
GPIO_MODE_OUTPUT_PP
*/
void dht_GPIO_Init(uint32_t DHT_Mode)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin : PB7 */
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = DHT_Mode;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
void delay_us(uint16_t cnt)
{
uint8_t i;
while(cnt)
{
for (i = 0; i < 10; i++)
{
}
cnt--;
}
}
void DHT11_Start()
{
dht_GPIO_Init(GPIO_MODE_OUTPUT_PP);
dht_HIGH;
dht_LOW;
HAL_Delay(20);
dht_HIGH;
dht_GPIO_Init(GPIO_MODE_INPUT);
while(read_dht);
while(!read_dht);
while(read_dht);
}
void Read_Data_From_DTH11()
{
int i,j;
char tmp;
char flag;
DHT11_Start();
dht_GPIO_Init(GPIO_MODE_INPUT);
for(i=0;i<5;i++){
for(j=0;j<8;j++){
while(!read_dht);
delay_us(40);//如果40us后读,读高电平就是代表1,读到低电平就是0
if(read_dht == SET){
flag = 1;
while(read_dht);
}else {
flag = 0;
}
tmp = tmp << 1;
tmp |= flag;
}
datas[i] = tmp;
}
}
void Show_DataToUart()
{
char hum[8];
char temp[8];
hum[0] = 'H';
hum[1] = ':';
hum[2] = datas[0]/10 + 0x30;
hum[3] = datas[0]%10 + 0x30;
hum[4] = '.';
hum[5] = datas[1]/10 + 0x30;
hum[6] = datas[1]%10 + 0x30;
hum[7] = '%';
temp[0] = 'T';
temp[1] = ':';
temp[2] = datas[2]/10 + 0x30;
temp[3] = datas[2]%10 + 0x30;
temp[4] = '.';
temp[5] = datas[3]/10 + 0x30;
temp[6] = datas[3]%10 + 0x30;
temp[7] = 'C';
HAL_Delay(1000);
printf(hum);
printf("\r\n");
printf(temp);
printf("\r\n");
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//printf("hello\n");
Read_Data_From_DTH11();
Show_DataToUart();
HAL_Delay(1000);
}
/* USER CODE END 3 */
}