历史上的今天

今天是:2024年11月02日(星期六)

2021年11月02日 | stm32实用篇5:HAL库 DHT11 驱动

发布者:RainbowDreamer 来源: eefocus关键字:stm32吗  HAL库  DHT11  驱动 手机看文章 扫描二维码
随时随地手机看文章

DHT11是很常用的温湿度传感器,时序也比较简单,如下所示:

直接给出HAL库的驱动:


1 微秒级延时函数


HAL库并没有直接的微秒级延时函数,下面是自己实现的微秒堵塞延时函数(使用定时器TIM3);


/**

* @brief 微秒级延时

*/

void bsp_delay_us(uint16_t us)

{

__HAL_TIM_SET_COUNTER(&htim3, 0);

HAL_TIM_Base_Start(&htim3);

while (__HAL_TIM_GET_COUNTER(&htim3) != us);

HAL_TIM_Base_Stop(&htim3);

}

2 配置DHT11数据引脚的输出模式和输入模式;


/**

* @brief DHT11 输出模式

*/

static void DHT11_Mode_OUT_PP(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = BSP_DHT11_PIN;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(BSP_DHT11_PORT, &GPIO_InitStruct);

}

 

/**

* @brief DHT11 输入模式

*/

static void DHT11_Mode_IN_NP(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = BSP_DHT11_PIN;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

 

  HAL_GPIO_Init(BSP_DHT11_PORT, &GPIO_InitStruct);

}

3 读取一个字节的数据(经过测试,延时时间最好设置为 40 ~ 60,这里我设置为50us);


/**

* @brief DHT11 读取字节

*/

uint8_t DHT11_ReadByte(void)

{

uint8_t i, temp = 0;

 

for (i = 0; i < 8; i++)

{

while (DHT11_IN == 0);    // 等待低电平结束

// 经过测试,这个值最好是 40 ~ 60,这里我选择 50 us

        bsp_delay_us(50);     // 至少延时 40 微秒  低电平为 0 ,高电平为 1

if (DHT11_IN == 1)

{

while (DHT11_IN == 1); // 等待高电平结束

temp |= (uint8_t)(0X01 << (7 - i));     // 先发送高位 MSB

}

else

{

temp &= (uint8_t)~(0X01 << (7 - i));

}

}

return temp;

}

4 完整的读取一次数据(读取数据间隔最好为2s及以上,不然容易出错);


/**

* @brief DHT11 读取一次数据

*/

uint8_t DHT11_ReadData(DHT11_Data_TypeDef *DHT11_Data)

{

DHT11_Mode_OUT_PP(); // 主机输出,主机拉低

DHT11_OUT_0;

HAL_Delay(18); // 延时 18 ms

DHT11_OUT_1; // 主机拉高,延时 30 us

bsp_delay_us(30);

 

DHT11_Mode_IN_NP(); // 主机输入,获取 DHT11 数据

if (DHT11_IN == 0) // 收到从机应答

{

while (DHT11_IN == 0); // 等待从机应答的低电平结束

while (DHT11_IN == 1); // 等待从机应答的高电平结束

/*开始接收数据*/   

DHT11_Data->humi_int  = DHT11_ReadByte();

DHT11_Data->humi_deci = DHT11_ReadByte();

DHT11_Data->temp_int  = DHT11_ReadByte();

DHT11_Data->temp_deci = DHT11_ReadByte();

DHT11_Data->check_sum = DHT11_ReadByte();

DHT11_Mode_OUT_PP(); // 读取结束,主机拉高

DHT11_OUT_1;

// 数据校验

if (DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci)

{

return 1;

}

else

{

return 0;

}

}

else // 未收到从机应答

{

return 0;

}

}

测试程序:


while (1)

{

if (DHT11_ReadData(&DHT11_Data))

{

DEBUG_INFO("rn读取DHT11成功!rnrn湿度为%d.%d %RH ,温度为 %d.%d℃ rn",

DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);

}

else

{

DEBUG_INFO("Read DHT11 ERROR!rn");

}

 

HAL_Delay(3000);

}

完整的驱动程序,仅供参考。


bsp_dht11.c


/**

******************************************************************************

* @file bsp_dht11.c

* @author

* @date

* @version v1.0

* @note DHT11 driver

******************************************************************************

*/

 

#include "tim.h"

#include "bsp_dht11.h"

 

/**

* @brief DHT11 输出模式

*/

static void DHT11_Mode_OUT_PP(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = BSP_DHT11_PIN;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(BSP_DHT11_PORT, &GPIO_InitStruct);

}

 

/**

* @brief DHT11 输入模式

*/

static void DHT11_Mode_IN_NP(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.Pin = BSP_DHT11_PIN;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

 

  HAL_GPIO_Init(BSP_DHT11_PORT, &GPIO_InitStruct);

}

 

/**

* @brief DHT11 读取字节

*/

uint8_t DHT11_ReadByte(void)

{

uint8_t i, temp = 0;

 

for (i = 0; i < 8; i++)

{

while (DHT11_IN == 0); // 等待低电平结束

bsp_delay_us(40); // 延时 40 微秒 低电平为 0 ,高电平为 1

if (DHT11_IN == 1)

{

while (DHT11_IN == 1); // 等待高电平结束

temp |= (uint8_t)(0X01 << (7 - i)); // 先发送高位 MSB

}

else

{

temp &= (uint8_t)~(0X01 << (7 - i));

}

}

return temp;

}

 

/**

* @brief DHT11 读取一次数据

*/

uint8_t DHT11_ReadData(DHT11_Data_TypeDef *DHT11_Data)

{

DHT11_Mode_OUT_PP(); // 主机输出,主机拉低

DHT11_OUT_0;

HAL_Delay(18); // 延时 18 ms

DHT11_OUT_1; // 主机拉高,延时 30 us

bsp_delay_us(30);

 

DHT11_Mode_IN_NP(); // 主机输入,获取 DHT11 数据

if (DHT11_IN == 0) // 收到从机应答

{

while (DHT11_IN == 0); // 等待从机应答的低电平结束

while (DHT11_IN == 1); // 等待从机应答的高电平结束

/*开始接收数据*/   

DHT11_Data->humi_int  = DHT11_ReadByte();

DHT11_Data->humi_deci = DHT11_ReadByte();

DHT11_Data->temp_int  = DHT11_ReadByte();

DHT11_Data->temp_deci = DHT11_ReadByte();

DHT11_Data->check_sum = DHT11_ReadByte();

DHT11_Mode_OUT_PP(); // 读取结束,主机拉高

DHT11_OUT_1;

// 数据校验

if (DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci)

{

return 1;

}

else

{

return 0;

}

}

else // 未收到从机应答

{

return 0;

}

}

 

// 测试程序

/*

while (1)

{

if (DHT11_ReadData(&DHT11_Data))

{

DEBUG_INFO("rn读取DHT11成功!rnrn湿度为%d.%d %RH ,温度为 %d.%d℃ rn",

DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);

}

else

{

DEBUG_INFO("Read DHT11 ERROR!rn");

}

HAL_Delay(3000);

}

*/

 

bsp_dht11.h


#ifndef __BSP_DHT11_H

#define __BSP_DHT11_H

 

#include "tim.h"

#include "stm32f1xx_hal.h"

 

#define BSP_DHT11_PORT DHT11_GPIO_Port

#define BSP_DHT11_PIN DHT11_Pin

 

#define DHT11_OUT_1 HAL_GPIO_WritePin(BSP_DHT11_PORT, BSP_DHT11_PIN, GPIO_PIN_SET)

#define DHT11_OUT_0 HAL_GPIO_WritePin(BSP_DHT11_PORT, BSP_DHT11_PIN, GPIO_PIN_RESET)

 

#define DHT11_IN HAL_GPIO_ReadPin(BSP_DHT11_PORT, BSP_DHT11_PIN)

 

typedef struct

{

uint8_t humi_int; // 湿度的整数部分

uint8_t humi_deci; // 湿度的小数部分

uint8_t temp_int; // 温度的整数部分

uint8_t temp_deci; // 温度的小数部分

uint8_t check_sum; // 校验和

                 

} DHT11_Data_TypeDef;

 

uint8_t DHT11_ReadData(DHT11_Data_TypeDef* DHT11_Data);

 

#endif /* __BSP_DHT11_H */

关键字:stm32吗  HAL库  DHT11  驱动 引用地址:stm32实用篇5:HAL库 DHT11 驱动

上一篇:stm32实用篇4: stm32数据类型长度
下一篇:stm32实用篇6:HAL库 DS18B20 驱动

推荐阅读

随着中国从世界工厂向消费市场角色的转变,中国成为一众国际品牌的必争之地,愈来愈多的外国品牌开始调整在中国市场的策略,以加快中国本土化步伐。其中,韩国品牌三星,在中国的本土化进程尤为显著。作为一个来华20余年的品牌,三星不仅深刻洞察中国消费者的真实需求,还将产品、服务和品牌的“本土化”之路提升到战略高度和实操执行层面,真...
11月1日,无人机制造商亿航于美东时间10月31日向美国证券交易委员会递交了招股说明书。招股书显示,亿航无人机在此次IPO中拟募资1亿美元。作为国内第一家在境外申请上市的无人机企业,这一举动,引起了广泛关注。从财务数据来看,从2017年到2019年,亿航一直处于亏损状态。2018年,亿航无人机营业收入分别为6650万元,较2017年的3170万元人民币增长了109....
在苹果A14、华为麒麟9000之后,又一款5nm手机芯片就要上市了,不过不是高通骁龙875,而是三星的Exynos 1080,官方宣布11月12日国内发布。 三星Exynos官微今天凌晨宣布了这一消息,这是三星Exynos国内首场线下发布会,将于11月12日举行,届时会正式发布Exynos 1080处理器。 Exyno...
之前在用stvd 在编译的时候出现的问题 !由于在网上找了 半天没有找到合理的解决方案 最后还是自己折腾了半天 弄出来的了选择这里 默认是Debug 然后将他改成Release编译一下,要是不放心 还可以Debug 一下 。然后 再重新选回Debug ,因为再Release 下面不能调试 汗!!然后错误就解决了!!

史海拾趣

问答坊 | AI 解惑

开关稳压电源(2007电子设计竞赛 E题)(内附论文和PCB图)

本帖最后由 paulhyde 于 2014-9-15 03:28 编辑 这是我去年作的,还请多多指教~!    …

查看全部问答∨

硬件汉字库使用原理

硬件汉字库使用原理…

查看全部问答∨

我在写辞职,被老板拒绝

本信息来自合作QQ群:AVR单片机学习与交流群(17727270) 群管理员在坛子里的ID:铜河 我在写辞职,被老板拒绝…

查看全部问答∨

见笑了,愚笨的问题。

低碳,环保等理念,加速了LED的发展,那么它表现在哪些方面呢?国内外LED的发展将带动哪些行业的发展?…

查看全部问答∨

基于ARM的DIS采集系统设计

0 引言   数字化信息系统实验室(Digital Information System,DIS)是新一代的中小学实验教学系统,是先进的数字技术应用到实验教学的产物,也是探究、创新的实验教学新理念注入传统实验教学后的必然结果。2006年,教育部将DIS纳入了中小学实验仪 ...…

查看全部问答∨

关于WinCE Flash播放器

有没有开源的解码器,或者比较好的实现方法?各位大侠指导一下。…

查看全部问答∨

Flash与S3C44B0X连接时地址线为什么要偏移一位,对应的代码也不甚清楚,劳烦各位大侠给看看。小弟先在此谢过了。

Flash与S3C44B0X连接时地址线为什么要偏移一位,对应的代码也不甚清楚,劳烦各位大侠给看看。小弟先在此谢过了。 Flash与S3C44B0X的接口电路图如图2所示。处理器ADDR20~1对应着Flash ROM的A19~0,偏移了1位,这是由于S3C44B0X是按照字节编址的, ...…

查看全部问答∨

求助:8051串口 中断接收 查询发送 数据丢失

用C8051F020与PC机之间串口通讯. 单片机用中断方式接收数据,用查询方式发送数据. 我的程序是为了实现:定义5字节数据为一帧,PC机向单片机发送数据,当数据到达一帧(5个字节)的时候,单片机向PC机将这一帧数据发送出去. 我用了2个BUFF,第1个BUFF用于 ...…

查看全部问答∨

关于wince的Alph的问题?

wince下的IE不能够支持Alpha吗?我想实现一些简单的特效,比如,淡出,渐显等图片效果,如何实现啊? …

查看全部问答∨

用C语言给51单片机编程时,怎么给外部单元的地址赋值(单片机的指针问题)

初学51单片机,有些问题请教! 我知道在标准c语言里面是不能给指定的一个地址单元赋值的,但是不知道单片机这里能不能这样。 问题1:keil c51中怎么才能使用DPTR寄存器?用keil时包含<reg51.h>后我可以使用DPH和DPL但是不能使用DPTR, ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved