一、DHT11产品介绍
DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。
二、典型应用电路
如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高有效位有线传输)
数据传送正确时校验和数据等于:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据,所得结果的末8位。
如:
湿度:60.5% 60 05
温度:26.7℃ 26 07
60+5+26+7=98
98&0xFF=98=1001 1000
三、DHT11温湿度模块的通信过程
四、示例代码
显示室内温度和湿度
效果图:
1、DHT11初始化
void dht11_init(void) { //打开端口G的硬件时钟,就是供电 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏 GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻 GPIO_Init(GPIOG,&GPIO_InitStructure); //只要有输出模式,肯定会有初始电平的状态,看连接设备的说明书 PGout(9)=1; }
2、
int32_t dht11_read(uint8_t *buf) { uint32_t t=0; int32_t i=0,j=0; uint8_t d=0; uint8_t *p=buf; uint8_t check_sum=0; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏 GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻 GPIO_Init(GPIOG,&GPIO_InitStructure); PGout(9)=0; delay_ms(18); PGout(9)=1; delay_us(30); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏 GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻 GPIO_Init(GPIOG,&GPIO_InitStructure); //等待低电平出现 t=0; while(PGin(9)) { t++; delay_us(1); if(t >= 4000) return -1; } //用超时检测的方法测量低电平的合法性 t=0; while(PGin(9)==0) { t++; delay_us(1); if(t >= 100) return -2; } //用超时检测的方法测量高电平的合法性 t=0; while(PGin(9)) { t++; delay_us(1); if(t >= 100) return -3; } for(j=0; j<5; j++) { //接收一个字节的数据 for(d=0,i=7; i>=0; i--) { //用超时检测的方法测量低电平的合法性 t=0; while(PGin(9)==0) { t++; delay_us(1); if(t >= 100) return -4; } //延时40us (延时时间在28us ~ 70us) delay_us(40); if(PGin(9)) { d|=1<<i; //将d变量对应的bit置1 //等待高电平持续完毕 t=0; while(PGin(9)) { t++; delay_us(1); if(t >= 100) return -5; } } } p[j]=d; } //延时50us,可以忽略通讯结束的低电平 delay_us(50); //计算校验和,检查接收到的数据是否准确 check_sum = (p[0]+p[1]+p[2]+p[3])&0xFF; if(check_sum == p[4]) return 0; return -6; }
3、main函数实现
int main(void) { uint8_t buf[5]; int32_t rt; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); /* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */ usart1_init(115200); dht11_init(); printf("this is dht11 test\r\n"); printf("1<<6=%X \r\n",1<<6); printf("1<<3=%X \r\n",1<<3); while(1) { rt = dht11_read(buf); if( rt == 0) { printf("T:%d.%d H:%d.%d\r\n",buf[2],buf[3],buf[0],buf[1]); } else { printf("dht11 read error code is %d\r\n",rt); } //官方要求,每6秒 delay_ms(6000); } }