目录
一、基础知识
1.功能:温湿度检测
2.应用范围
3.硬件电路连接
二、底层代码原理分析
1.基础知识
1.单总线说明
2.单总线传送数据位定义
3.数据格式
4.校验位数据定义
2.代码分析
1.数据时序图
2.数据传输步骤
一、基础知识
1.功能:温湿度检测
测量范围湿度:湿度:5-95%RH 精度:(±5)%RH
温度:-20-60℃ 精度:(±2)℃
2.应用范围
暖通空调、除湿器、农业、冷链仓储、测试及检测设备、消费品、汽车、自动控制、数据记录器、气 象站、家电、湿度调节器、医疗、其他相关湿度检测控制。
3.硬件电路连接
1.VDD 供电 3.3~5.5V DC
2.DATA 串行数据,单总线
3.NC 空脚
4.GND 接地,电源负极
注意点:
1. 建议连接线长度短于 5m 时用 4.7K 上拉电阻,大于 5m 时根据实际情况降低上拉电 阻的阻值。
2. 使用 3.3V 电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。
3. 每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取 2 次,但不建议连续多次 读取传感器,每次读取传感器间隔大于 2 秒即可获得准确的数据。
4. 电源部分如有波动,会影响到温度。如使用开关电源纹波过大,温度会出现跳动。
二、底层代码原理分析
1.基础知识
1.单总线说明
DHT11 器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线 完成。它们是主从结构,只有主机呼叫从机时,从机才能应答。
2.单总线传送数据位定义
DATA 用于微处理器与 DHT11 之间的通讯和同步,采用单总线数据格式,一次传送 40 位数据,高位先出。
3.数据格式
8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位。
注:其中湿度小数部分为 0。
4.校验位数据定义
“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据”8bit 校验位等于 所得结果的末 8 位
2.代码分析
1.数据时序图
用户主机(MCU)发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束 后,DHT11 发送响应信号,送出 40bit 的数据,并触发一次信采集。信号发送如图所示。
注:主机从 DHT11 读取的温湿度数据总是前一次的测量值,如两次测间隔时间很长,请连续读两次以 第二次获得的值为实时温湿度值。
2.数据传输步骤
步骤一二三准备步骤即初始化。步骤四发送数据。
步骤一
DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境 温湿度数据,并记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的 DATA 引脚处于输入状态,时刻检测外部信号。
步骤二:
上图中主机发送信号:
微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms), 然后微处理器的 I/O 设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变 高,等待 DHT11 作出回答信号,发送信号如图所示:
由此得到代码:
DHT11_IO_OUT();设置为引脚输出模式的函数,写个函数(简单)或直接宏定义寄存器操作(简洁);DHT11_IO_IN()同理;
DHT11_DQ_OUT();即引脚输出高电平,可以用位带操作宏定义一番;DHT11_DQ_IN();同理;
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_OUT=0; //拉低DQ
delay_ms(20); //拉低至少18ms
DHT11_DQ_OUT=1; //DQ=1
delay_us(30); //主机拉高20~40us
DHT11_IO_IN();
}
步骤三:
DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA 引脚处于输出状态,输出 83 微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接 收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 87 微秒 的高电平后的数据接收,发送信号如 图所示:
DHT11输出,主机接收所以配置输入模式。
由此得到代码:
两个while循环一个检测低电平一个检测高电平。retry其实就是高低电平时间。
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN();
while (DHT11_DQ_IN&&retry<100)//DHT11会拉低
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
步骤四:
由 DHT11 的 DATA 引脚输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据,位数据“0” 的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加 68-74 微秒的高电平。位数据“0”、“1”格式信号如图所示
通过对比得到0,1不同处在于高低电平时间
所以我们先等度过低电平,高电平到来然后延时40us,此时如果他是低电平,那接收到的数据就是0,如果是高电平那他就是1。
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_DQ_IN)//等待变为低电平
while(!DHT11_DQ_IN)//等待成为高电平
delay_us(40);//等待40us
if(DHT11_DQ_IN)
return 1;
else
return 0;
}
根据前文:“一次传送 40 位数据,高位先出。”我们优化代码:
u8 DHT11_Read_Byte(void)
{
u8 dat1,dat2=0;
for(data1=0x80;data1!=0;data1>>1)
{
if(DHT11_Read_Bit())
data2|=data1;
else
data2&=~data1;
}
return data2;
}
步骤五:结束信号
DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 54 微秒后转为输入状态,由于上拉电阻随 之变为高电平。但 DHT11 内部重测环境温湿度数据,并记录数据,等待外部信号的到来。
根据上文校验位结构:“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据”8bit 校验位等于 所得结果的末 8 位。
得出代码:文章来源:https://www.toymoban.com/news/detail-402047.html
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++)//读取40位数据
{
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;
}
我们最终顺其自然的得到主函数文章来源地址https://www.toymoban.com/news/detail-402047.html
int main(void)
{
u8 temper;
u8 humi;
u8 temp;
delay_init();
DHT11_Init();
oled_init();
while(1)
{
temp = DHT11_Read_Data(&temper,&humi);
if(temp ==0)
{
OLED_ShowNum(10,10,humi,5,16);
OLED_ShowNum(10,30,temper,5,16);
}
};
}
到了这里,关于stm32-DHT11原理及代码解读的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!