蓝桥杯国赛之温湿度传感器
时间:2022-11-22 07:00:00
一、温湿度传感器
DHT11是单线接口数字温湿度传感器,温度测量范围为0~50℃,湿度测量范围为20%~90%RH,温度测量精度为±2℃,湿度测量精度为±5%RH。
DHT11包含电阻式感湿元件和一个NTC通过(负温度系数)测温元件双向单线输出温湿度数据,一次数据输出40位(高位在前,需要4左右ms),数据格式如下: 8位湿度整数 8位湿度小数 8位温度整数 8位温度小数 8位校验和。校验和前四个八位数据之和。
二、通信原理
用户MCU发送开始信号后, DHT从低功耗模式到高速模式,等待主机开始信号结束, DHT11发送响应信号40bit用户可以选择读取部分数据,触发信号采集。
从模式下, DHT如果没有接收到主机发送的开始信号,11接收到开始信号触发温湿度采集, DHT11不主动采集温湿度。收集数据后转换为低速模式。
开始信号:
总线的空闲状态是高电平,主机拉下总线等待DHT11响应,主机拉下总线必须大于18毫秒,保证DHT起始信号可以检测到。
DHT11收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号后,延时等待20-40us后,读取DHT11响应信号,主机发送开始信号后,可切换到输入模式,或平均输出高电,总线由上拉电阻拉高。
//复位DHT11 void DHT11_Rst(void) { DHT11_PIN_OUT(); //设置为输出 DHT11_PIN_OUT_L; //低电平 HAL_Delay(20); /至少拉18ms DHT11_PIN_OUT_H; //高电平 Delay_us(60); ///主机拉高20~40us }
等待应答:
总线为低电平,说明DHT11发送响应信号, DHT11发送响应信号后,再把总线拉高80us,准备发送每一个数据bit数据都以50us低电平时间隙开始, 数据位的长度决定了数据位是0还是1。若读取响应信号为高电平, 则DHT11无响应,请检查线路连接是否正常。当最后一个bit数据传输后,DHT11拉低总线50us,然后总线从上拉电阻拉高到空闲状态。
//等待DHT11的回应 //返回1:未检测到DHT11的存在 //返回0:存在 uint8_t DHT11_Check(void) { uint8_t re = 0; DHT11_PIN_INPUT(); //设置为输出 while (DHT11_PIN_IN && re < 100) //DHT11会拉低40~80us { re ; Delay_us(1); }; if(re >= 100)return 1; else re = 0; while (!DHT11_PIN_IN && re < 100) //DHT11拉低后,将再次拉40~80us { re ; Delay_us(1); }; if(re >= 100)return 1; return 0; }
读动作:
数字0表示:
数字1表示:
每个数据都是50us从低压电平开始,随后的高压电平信号长度决定了数据位是0还是1。us - 28us 表示0,70us表示1。
//从DHT11读取一个位 uint8_t DHT11_Read_Bit(void) { uint8_t re = 0; while(DHT11_PIN_IN && re < 110) //等待变成低电平 { re ; Delay_us(1); } re = 0; while(!DHT11_PIN_IN && re < 110) //等待变高电平 { re ; Delay_us(1); } Delay_us(80)us if(DHT11_PIN_IN)return 1; else return 0; } //从DHT读一个字节 uint8_t DHT11_Read_Byte(void) { uint8_t i, dat; dat = 0; for (i = 0; i < 8; i ) { dat <<= 1; dat |= DHT11_Read_Bit(); } return dat; }
三、程序
电路原理图
需要将HDQ和PA7用跳线帽连接。
从DHT读取数据,共5个字节,对应温度、湿度、验证位置。
//从DHT读取一次数据 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 ) { buf[i] = DHT11_Read_Byte(); } if((buf[0] buf[1] buf[2] buf[3]) == buf[4]) { *humi = buf[0]; *temp = buf[2]; } } else return 1; return 0; } uint8_t temp=0,humi=0; ///读取数据 DHT11_Read_Data(&temp, &humi);
由于DHT11测量湿度精度5%RH,测温精度为 2摄氏度,所以这里只读整数部分,省略了小数部分,官方例程也是这样写的。