马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
STM32实战——DHT11温湿度获取并展示
媒介
本文重要阐明温湿度传感器(DHT11)在STM32下怎样使用,而且团结OLED屏来到达体现的效果。喜好的话可以点个赞和收藏噢!!以下内容均为查询干系资料撰写而成,如有侵权,请接洽作者。
一、前期预备
硬件方面:
盘算机、0.96寸体现屏、DHT11温湿度模块、STM32最小体系板、ST-Link下载器、面包板、杜邦线多少(9根)。
软件方面:
KEIL_5软件、Typora(可选)
二、接线图表
STM32ST-LinkOLED屏DHT113V33.3VSWOSWDIOSWCLKSWCLKGNDGNDPB9SDAPB8SCL3.3VCCGGND3.3+PB11outG-三、温湿度传感器(DHT11)驱动
(一)原理
DHT11工作原理是基于内部的湿度传感器和温度传感器,通过检测这两个传感器的信号变革,将湿度和温度转换为数字信号输出。它接纳简单的串行通讯协议(反面增补)与外部装备通讯,发送包罗温湿度数据的数据帧,用户则获取数据帧举行干系的处置惩罚使用。
经典应用电路图如图1所示
DHT11在待机模式下斲丧极低的电量,险些可以忽略不计,这使得它非常得当电池供电的低功耗应用场景。 为了有用管理功耗,DHT11具备休眠和叫醒机制。 DHT11在没有丈量任务时,会自动进入深度就寝模式,这个过程是自动的,无需外部干预。 叫醒DHT11时,微控制器须要通过发送信号给DHT11,这通常是一个从低到高的电平变革信号,用于启动丈量过程。 叫醒过程的时序要求非常严酷,须要精确控制信号的连续时间。
DATA 用于微处置惩罚器与 DHT11之间的通讯和同步,接纳单总线数据格式,一次通讯时间4ms左右,数据分小数部门和整数部门,具体格式在下面阐明,当前小数部门用于以后扩展,现读出为零。使用流程如下:
一次完备的数据传输为40bit,高位先出。
数据格式:
8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和数据传送精确时校验的和
数据便是“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据” 所得效果的末8位。用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等候主机开始信号竣事后,DHT11发送相应信号,送出40bit的数据,并触发一次信号收罗,用户可选择读取部门数据。从模式下,DHT11吸收到开始信号触发一次温湿度收罗,如果没有吸收到主机发送开始信号,DHT11不会自动举行温湿度收罗。收罗数据后转换到低速模式。
通讯过程如下图所示:
总线空闲状态为高电平,主机把总线拉低等候DHT11相应,主机把总线拉低必须大于18毫秒,包管DHT11能检测到起始信号。DHT11吸收到主机的开始信号后,等候主机开始信号竣事,然后发送80us低电平相应信号。主机发送开始信号竣事后,延时等候20-40us后,读取DHT11的相应信号,主机发送开始信号后,可以切换到输入模式,大概输出高电匀称可,总线由上拉电阻拉高。
如下图所示:
总线为低电平,阐明DHT11发送相应信号,DHT11发送相应信号后,再把总线拉高80us,预备发送数据,每一bit数据都以50us低电平常隙开始,高电平的是非定了数据位是0还是1。格式见下面图示。如果读取相应信号为高电平,则DHT11没有相应,请查抄线路是否毗连正常。当末了一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
数字0信号表现方法如图所示:
数字1信号表现方法如图所示:
增补内容:
串行通讯协议是一种在数据传输中将信息逐位发送的通讯方式。对于DHT11传感器而言,它使用的是一种简单的串行通讯协议,通常是通过单个数据线与外部装备举行通讯。具体来说,DHT11使用串行通讯协议与外部装备通讯的过程包罗以下几个步调:
启动信号: 外部装备发送一个启动信号给DHT11传感器,以指示开始通讯的预备阶段。
数据传输: DHT11传感器根据约定的协议,将温湿度数据以串行的情势发送给外部装备。这些数据以特定的格式构造,比方先发送湿度值,然后发送温度值,大概相反。
校验: 在数据传输完成后,外部装备大概会对吸收到的数据举行校验,以确保数据的完备性和精确性。通常使用校验和或循环冗余校验(CRC)等技能来实现校验。
应答: 在数据传输完成后,DHT11大概会发送一个应答信号给外部装备,以表现数据传输的乐成或失败状态。
(二)代码剖析
1. void DHT_Init_InPut(void)函数
函数先容:
这个函数用于将毗连到DHT11传感器的GPIO引脚设置为浮空输入模式。
使用了STM32的GPIO初始化布局体(GPIO_InitStructure)来设置GPIO的模式、引脚、速率等参数。
- void DHT_Init_InPut(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
复制代码 DHT11数据引脚设置为浮空输入的焦点缘故起因是其单总线通讯协议的特殊性:该总线须要主机(MCU)和从机(DHT11)分时复用同一根线举行双向通讯。浮空输入模式能确保在主机不自动驱动时,总线被外部上拉电阻拉高,为从机相应创造精确的电气条件。
2. void DHT_Init_OutPut(void)函数
函数先容:
这个函数将毗连到DHT11传感器的GPIO引脚设置为推挽输出模式。
同样使用了GPIO初始化布局体举行设置。
- void DHT_Init_OutPut(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
复制代码 这段代码的作用,是让MCU作为主机,向DHT11发送一个至少18ms的低电平信号作为通讯开始的“拍门”指令。在这个短暂的时候,引脚必须为强推挽输出,以确保连续、稳固地拉低总线。
3. void DHT_Start(void)函数
函数先容:
这个函数用于启动与DHT11传感器的通讯。
起首调用了DHT_Init_OutPut()将引脚设置为输出模式,然后拉低总线一段时间(19ms),再拉高总线(20us),末了将引脚设置为输入模式。
- void DHT_Start(void)
- {
- DHT_Init_OutPut();
- GPIO_ResetBits(GPIOB, GPIO_Pin_11); // 拉低总线
- Delay_us(19000);
- GPIO_SetBits(GPIOB, GPIO_Pin_11); // 拉高总线
- Delay_us(20);
- DHT_Init_InPut();
- }
复制代码 4. uint16_t DHT_Scan(void)函数
函数先容:
这个函数用于读取毗连到DHT11传感器的GPIO引脚的当前状态,即读取传感器的相应状态。
- uint16_t DHT_Scan(void)
- {
- return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11); // 返回读取数据
- }
复制代码 5. uint16_t DHT_ReadBit(void)函数
函数先容:
这个函数用于从DHT11传感器读取单个位。
它会等候传感器将数据线拉高,然后延时一段时间后再读取数据线的状态,以确定位值。
- uint16_t DHT_ReadBit(void)
- {
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == RESET); // 每一bit数据都以50us低电平时隙开始
- Delay_us(40);
- if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == SET) // 高是1,否则是0
- {
- while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == SET);
- return 1;
- }
- else
- {
- return 0;
- }
- }
复制代码
6. uint16_t DHT_ReadByte(void)函数
函数先容:
这个函数用于从DHT11传感器读取一个字节(8位)的数据。
它通过调用DHT_ReadBit()函数8次,将每一位数据组装成一个完备的字节。
[code]uint16_t DHT_ReadByte(void){ uint16_t i, data = 0; for(i = 0; i < 8; i++) { data |