目录
| 湿度量程 | 5 - 95 %RH | 误差:±5%RH(25℃) |
| 湿度量程 | -20 - 60 ℃ | 误差:±2℃(25℃) |
| 供电电压 | 3.3 - 5.5 | 单位:V |
| 供电电流 |
0.06(待机) 、1.0(测量)
| 单位:mA |
| 采样周期 | >2 | 单位:s |
| VDD |
供电3.3~5.5V DC
|
| DATA |
串行数据,单总线
|
| NC |
空脚
|
| GND |
接地,电源负极
|
1、典型应用电路中建议连接线长度短于5m时用4.7K上拉电阻,大于5m时根据实际情况降低上拉电阻的阻值。2、使用3.3V电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。3、每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取2次,但不建议连续多次读取传感器,每次读取传感器间隔大于2秒即可获得准确的数据。4、电源部分如有波动,会影响到温度。如使用开关电源,温度就会跳动。
DHT11器件采用单总线通信来实现数据交换和控制,这种通信方式只有一根数据线。设备可以通过漏极开路或三态端口连接到数据线上,以允许设备在不发送数据时释放总线并让其他设备使用。为了让总线保持高电平状态,通常需要外接一个约4.7kΩ的上拉电阻。由于DHT11器件采用主从结构,只有在主机呼叫从机时,从机才能作出响应。因此,主机访问DHT11器件时必须严格遵循单总线序列,否则器件将不会响应主机。
DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。注:其中湿度小数部分为0。
“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”8bit校验位等于所得结果的末8位。
校验位=湿度高位+湿度低位+温度高位+温度低位
首先主机发送开始信号,即:拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2(20~40us)时间,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间后,开始输出数据。
(1)IO方向设置和输出设置
- //IO方向设置
- #define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8;}
- #define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3;}
- //IO操作函数
- #define DHT11_DQ_OUT(x) {if(x==0) GPIO_ResetBits(GPIOA,GPIO_Pin_0); else if(x==1) GPIO_SetBits(GPIOA,GPIO_Pin_0);}//数据端口
- #define DHT11_DQ_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //数据端口
(2)STM32发出复位信号

拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2 (20~40us)时间
- void DHT11_Rst(void)
- {
- DHT11_IO_OUT(); //SET OUTPUT
- DHT11_DQ_OUT(0); //拉低DQ 至少18ms
- delay_ms(20);
- DHT11_DQ_OUT(1); //主机拉高20~40us
- delay_us(30);
- }
(3)等待DHT11回应(检测DHT11是否存在)

DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间
- u8 DHT11_Check(void)
- {
- u8 retry = 0;
- DHT11_IO_IN();//SET INPUT
-
- while(DHT11_DQ_IN && retry < 100) //DHT11会拉低40~80us(拉低会跳出while)
- {
- retry++;
- delay_us(1);
- }
-
- if(retry >= 100)
- return 1;
- else
- retry = 0;
-
- while(!DHT11_DQ_IN && retry < 100) //DHT11拉低后会再次拉高(DHT11_DQ_IN = 1)40~80us (!DHT11_DQ_IN 为0 跳出while 表示DHT11拉高)
- {
- retry++;
- delay_us(1);
- }
-
- if(retry >= 100)
- {
- return 1;
- }
-
- return 0;
- }
(4)读一个位数据
DHT11发送0时序

首先12-14us的开始信号,然后是26-28us高电平(代表0)
DHT11发送1时序

首先12-14us的开始信号,然后是116-118us高电平(代表1)
- u8 DHT11_Read_Bit(void)
- {
- u8 retry = 0;
-
- while(DHT11_DQ_IN && retry < 100) //主机读时 DHT11会先拉低12~14us(拉低会跳出while)
- {
- retry++;
- delay_us(1);
- }
-
- if(retry >= 100)
- return 1;
- else
- retry = 0;
-
- while(!DHT11_DQ_IN && retry < 100) //主机读时 为0(再拉高26~28us) 为1(再拉高116~118us)
- {
- retry++;
- delay_us(1);
- }
-
- delay_us(40); //等40us 判断此时电位 高电平为1 低电平为0
-
- if(DHT11_DQ_IN)
- return 1;
- else
- return 0;
- }
(5)读一个字节数据
- u8 DHT11_Read_Byte(void)
- {
- u8 i, dat;
- dat = 0;
-
- for (i = 0; i < 8; i++)
- {
- dat <<= 1;
- dat |= DHT11_Read_Bit();
- }
-
- return dat;
- }
(6)一次性读取数据并校验
- 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++)
- {
- buf[i] = DHT11_Read_Byte(); //5个字节读入buf数组
- }
-
- if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])//校验 前四个字节和等于第五个字节
- {
- *humi = buf[0];
- *temp = buf[2];
- }
- }
- else
- return 1;
-
- return 0;
- }
(7)初始化代码
- u8 DHT11_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PC端口时钟
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC2端口配置
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口
- GPIO_SetBits(GPIOA, GPIO_Pin_0); //PC2 输出高
-
- DHT11_Rst(); //复位DHT11
- return DHT11_Check();//等待DHT11的回应
- }
说明:本文章部分内容参考 ASARI温湿度模块DHT11 产品手册
以上就是DHT11的所有内容了,更多传感器驱动代码请订阅我的传感器专栏