STM32之DHT11温湿度传感器---附代码

时间:2025-04-27 08:48:04
#include "stm32f10x.h" // Device header #include "DHT11.h" #include "Delay.h" /*DHT11数据线为输出模式*/ void DHT11_IO_OUT(void) { RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO时钟和AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用JTAG,保留SWD GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); } /*DHT11数据线为输入模式*/ void DHT11_IO_IN(void) { RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO时钟和AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用JTAG,保留SWD GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式 GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure); } /*复位DHT11传感器*/ void DHT11_Rst(void) { DHT11_IO_OUT(); //设置输出模式 DHT11_DQ_OUT = 0; //将数据线拉低,等待DHT11响应 Delay_ms(20); //拉低至少18ms,保证DHT11能检测到起始信号 DHT11_DQ_OUT = 1; //将数据线拉高 Delay_us(30); //主机拉高20~40us,读取DHT11的响应信号 } /*检查DHT11是否存在*/ //返回1:未检测到DHT11的存在 //返回0:检测到DHT11的存在 uint8_t DHT11_Check(void) { uint8_t retry = 0; DHT11_IO_IN(); //设置输入模式 //DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号 //DHT11发送响应信号后,再把总线拉高80us,准备发送数据 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 uint8_t DHT11_Read_Bit(void) { uint8_t retry = 0; //每1bit数据都以50us低电平时隙开始 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 //高电平的长短定了数据位是0还是1 //26us-28us表示0,70us表示1 if(DHT11_DQ_IN) return 1; else return 0; } /*DHT11读取一个字节*/ //返回值:读到的数据 uint8_t DHT11_Read_Byte(void) { uint8_t i,data; data = 0; for (i = 0; i < 8; i++) { data<<=1; data |= DHT11_Read_Bit(); } return data; } /*DHT11读取一次数据*/ //temp:温度值(范围:0~50°) //humi:湿度值(范围:20%~90%) //返回值:0,正常;1,读取失败 uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi) { uint8_t buf[5]; uint8_t i; DHT11_Rst(); if(DHT11_Check() == 0) { for(i = 0; i < 5; i++) //读取40位数据 { buf[i] = DHT11_Read_Byte(); } //数据格式:8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据 + 8bit校验和 //8bit校验和 = 8bit湿度整数数据 + 8bit湿度小数数据 + 8bit温度整数数据 + 8bit温度小数数据 if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) //校验数据 { *humi = buf[0]; *temp = buf[2]; } }else return 1; return 0; } //初始化DHT11的IO口同时检测DHT11是否存在 //返回1:不存在 //返回0:存在 uint8_t DHT11_Init(void) { DHT11_Rst(); //复位DHT11 return DHT11_Check(); //等待DHT11的回应 }