DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃,最远可测得20m以内得温湿度。
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测型号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用甚至最为苛刻的应用场合的最佳选择。
根据在这个通信协议进行通信。
下面进行端口的配置
然后编写DHT11.c和DHT11.h文件
DHT11.c
#include "dht11.h"
#include "main.h"
void DHT11_IO_OUT (void){ //端口变为输出
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void DHT11_IO_IN (void){ //端口变为输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_DA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
DHT11_IO_OUT();
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);
HAL_Delay(20); //拉低至少18ms
HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);
delay_us(30); //主机拉高20~40us
}
uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
uint8_t retry=0;
DHT11_IO_IN();//IO到输入状态
while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1; else retry=0;
while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80us
retry++;
delay_us(1);
}
if(retry>=100)return 1;
return 0;
}
uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
uint8_t retry=0;
while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平
retry++;
delay_us(1);
}
retry=0;
while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平
retry++;
delay_us(1);
}
delay_us(40);//等待40us //用于判断高低电平,即数据1或0
if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}
uint8_t Dht11_ReadByte(void){ //从DHT11读取一个字节 返回值:读到的数据
uint8_t i,dat;
dat=0;
for (i=0;i<8;i++){
dat<<=1;
dat|=Dht11_ReadBit();
}
return dat;
}
uint8_t DHT11_Init (void){ //DHT11初始化
DHT11_RST();//DHT11端口复位,发出起始信号
return Dht11_Check(); //等待DHT11回应
}
uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
uint8_t buf[5];
uint8_t i;
DHT11_RST();//DHT11端口复位,发出起始信号
if(Dht11_Check()==0){ //等待DHT11回应
for(i=0;i<5;i++){//读取5位数据
buf[i]=Dht11_ReadByte(); //读出数据
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){ //数据校验
*h=buf[0]; //将湿度值放入指针1
h++;
*h=buf[2]; //将温度值放入指针2
}
}else return 1;
return 0;
}
DHT11.h
#ifndef DHT11_DHT11_H_
#define DHT11_DHT11_H_
#include "stm32f1xx_hal.h"
#include "../delay/delay.h"
void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);
#endif /* DHT11_DHT11_H_ */
然后在主程序中,调用头文件,并在main.c中进行操作
这里的初始化需要进行传感器的第一次数据获取
最后打开串口,就可以查看到数据的传输了。
总结:
当第一次做这些的时候,看见单总线协议自己如果不知道怎么写,就去网上查询,看别人怎么写的,在进行协议的修改。