开发环境:
IDE:RT-Thread Studio 2.2.7
开发板:HPM5300EVK
1 理论分析
1.1 DHT11介绍
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。
DHT11传感器包括一个__电阻式感湿元件和一个 NTC 测温元件__,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个 DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在 OTP 内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达 20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为 4 针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。
DHT11 的技术参数如下:
- 工作电压范围: 3.3V-5.5V
- 工作电流 :平均 0.5mA
- 输出:单总线数字信号
- 测量范围:湿度 20
90%RH,温度 050℃
- 精度 :湿度±5%,温度±2℃
- 分辨率 :湿度 1%,温度 1℃
1.2 MCU读取 DHT11
DHT11模块的数据管脚用于 MCU与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间 4ms 左右,一次完整的数据传输为 40bit,高位先出,数据分小数部分和整数部分,具体格式是:
8bit 湿度整数数据+8bit 湿度小数数据+8bi 温度整数数据+8bit 温度小数数据 +8bit校验和数据传送正确时校验和数据等于 8bit 湿度整数数据+8bit 湿度小数数据+8bi 温度整数数据+8bit 温度小数数据所得结果的末 8 位。
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如下所示。
由以上数据就可得到湿度和温度的值,计算方法:
湿度= byte4 . byte3=45.0 (%RH)
温度= byte2 . byte1=28.0 ( ℃)
校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确)
可以看出, DHT11 的数据格式是十分简单的, DHT11 和 MCU 的一次通信最大为 3ms 左右,建议主机连续读取时间间隔不要小于 100ms。
下面,介绍一下 DHT11 的传输时序。
1.主机与DHT11通讯流程
主机MCU 发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,等待主机开始信号结束后,即:拉低数据线,保持至少 18ms时间,然后拉高数据线 20~40us时间。DHT11 发送响应信号,送出 40bit 的数据,并触发一次信号采集,用户可选择读取部分数据。正常情况, DHT11 会拉低数据线,保持80us时间,作为响应信号,然后 DHT11 拉高数据线,保持80us时间后,开始输出数据。DHT11 接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11 不会主动进行温湿度采集。采集数据后转换到低速模式。
2.主机复位信号和 DHT11 响应信号
总线空闲状态为高电平,主机把总线拉低等待 DHT11 响应,主机把总线拉低必须大于 18 毫秒,保证 DHT11 能检测到起始信号。DHT11 接收到主机的开始信号后,等待主机开始信号结束,然后发送 80us 低电平响应信号。主机发送开始信号结束,延时等待 80us 后,读取 DHT11 的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高,如图中黑色线所示
总线为低电平,说明 DHT11 发送响应信号,DHT11 发送响应信号后,再把总线拉高 80us,准备发送数据,每一 bit 数据都以 50us 低电平时隙开始,高电平的长短定了数据位是 0 还是 1。格式如图中灰色线所示。如果读取响应信号为高电平,则 DHT11 没有响应,请检查线路是否连接正常。当最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,随后总线由上拉电阻拉高进入空闲状态。
3.数字‘ 0’信号表示方法
数字 0 信号表示方法如图所示
4.数字‘ 1’信号表示方法
数字 1 信号表示方法如图所示
这里我们可以看出,数字“0”和数字“1”不同的地方在于高电平的时间不同,这也是读取数据的关键所在。
2 实验详解
2.1 实验相关电路图
DHT11模块相关电路途如下图所示:
传感器模块是单总线通信,单总线通常要求外接一个4.7kΩ的上拉电阻,这样,当总线闲置时,总线上始终是高电平
【注】VCC接开发板的3.3V、GND 接开发板的GND、DATA接到开发板的PB8上,当然,也可以接到其他引脚上,修改相应的GPIO代码即可。
2.2 DHT11数据读取实现
代码很简单。主要是根据DHT11的操作即可。
这里直接使用DHT11的软件包即可,当然也可以自己实现。
另外还需要配置相应的组件。
最后保存相应的组件包。
指定相应的PIN。
另外需要高精度延时,替换原来的延时函数。
#define MTIMER_CORE_CLOCK 24000000
uint32_t mtime_lo(void)
{
return ((HPM_MCHTMR->MTIME) & 0xFFFFFFFF) ;
}
uint32_t mtime_hi(void)
{
return (((HPM_MCHTMR->MTIME) >> 32) & 0xFFFFFFFF);
}
uint64_t get_timer_value(void)
{
uint64_t value = 0;
uint64_t hi;
uint64_t lo;
while(1)
{
hi = mtime_hi();
lo = mtime_lo();
if(hi == mtime_hi())
{
value = ((uint64_t)((hi << 32)) | lo);
break;
}
}
return value;
}
void delay_us(uint32_t nus)
{
uint64_t start_mtime;
uint64_t delta_mtime;
uint64_t tmp = 0;
tmp = get_timer_value();
do
{
start_mtime = get_timer_value();
}while(start_mtime == tmp);
do
{
delta_mtime = get_timer_value() - start_mtime;
}while(delta_mtime <(MTIMER_CORE_CLOCK / 1000000 * nus));
}
void rt_hw_us_delay(rt_uint32_t us)
{
delay_us(us);
}
当然还可以使用定时器来实现延时。
2.3 实验现象
接上设备,每隔1s就输出温湿度。