stm32用HAL库驱动DHT22使用心得

这篇是本人自己总结学习DHT22的笔记,源码在最后。关于DHT22的工作原理有很多博主讲得很好了,本篇主要讲解DHT22的驱动代码(都在代码注释上)。DHT22是单总线通信的,驱动它需三根线:电源线、信号线(接到任意GPIO口就行)和地线,,如下图

查看源图像

 

 

具体的原理解释见该博主:温湿度模块DHT22详解一:基础篇_k1ang的博客-CSDN博客_dht22

以下的工作原理是从DHT22的使用说明中截取的时序图

数据格式: 40bit数据=16bit湿度数据+16bit温度数据+8bit校验和

例子: 接收40bit数据如下:

0000 0010 1000 1100 0000 0001 0101 1111 1110 1110

         湿度数据                     温度数据                校验和

湿度高8位+湿度低8位+温度高8位+温度低8位=的末8位=校验和

例如:0000 0010+1000 1100+0000 0001+0101 1111=1110 1110

湿度=65.2%RH 温度=35.1℃

当温度低于0℃时温度数据的最高位置1。

例如:-10.1℃表示为1000 0000 0110 0101

用户主机(MCU)发送一次开始信号后,DHT22从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT22发送响应信号,送出40bit的数据,并触发一次信号采集。(注:主机DHT22读取的温湿度数据总是前一次的测量值,如两次测量间隔时间很长,请连续读两次以获得实时的温湿度值)

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将DHT11的VCC引脚连接到STM32的5V电源引脚,将DHT11的GND引脚连接到STM32的GND引脚。将DHT11的数据引脚连接到STM32的任意IO引脚,比如PA0。 为了读取DHT11传感器数据,需要进行以下步骤: 1. 初始化GPIO口为输出模式,将数据引脚拉低至少18ms,然后将其拉高20~40us,再将其拉低80us。 2. 将GPIO口设置为输入模式,等待DHT11响应信号。 3. 接收DHT11的响应信号,即一个80us的低电平后,一个80us的高电平。 4. 接收DHT11传输的数据,每个数据位由50us的低电平和26~28us的高电平组成,高电平时间长表示数据位为1,高电平时间短表示数据位为0。 5. 解析数据,得到湿度和温度值。 下面是一个示例代码: ```c #include "stm32f10x.h" #define DHT11_GPIO GPIOA #define DHT11_PIN GPIO_Pin_0 void DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = DHT11_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DHT11_GPIO, &GPIO_InitStructure); GPIO_ResetBits(DHT11_GPIO, DHT11_PIN); Delay_ms(20); GPIO_SetBits(DHT11_GPIO, DHT11_PIN); Delay_us(30); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DHT11_GPIO, &GPIO_InitStructure); } uint8_t DHT11_ReadByte(void) { uint8_t i, byte = 0; for (i = 0; i < 8; i++) { while (!GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)); //等待数据位开始 Delay_us(30); if (GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)) { byte |= (1 << (7 - i)); //高电平表示数据位为1 } while (GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)); //等待数据位结束 } return byte; } uint8_t DHT11_ReadData(uint8_t *data) { uint8_t i, checksum; uint8_t buf[5]; GPIO_ResetBits(DHT11_GPIO, DHT11_PIN); Delay_ms(20); GPIO_SetBits(DHT11_GPIO, DHT11_PIN); Delay_us(30); GPIO_ResetBits(DHT11_GPIO, DHT11_PIN); Delay_us(80); GPIO_SetBits(DHT11_GPIO, DHT11_PIN); Delay_us(30); if (!GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)) { while (!GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)); //等待DHT11响应信号 while (GPIO_ReadInputDataBit(DHT11_GPIO, DHT11_PIN)); for (i = 0; i < 5; i++) { buf[i] = DHT11_ReadByte(); //读取数据 } checksum = buf[0] + buf[1] + buf[2] + buf[3]; if (checksum == buf[4]) //校验和 { data[0] = buf[0]; data[1] = buf[2]; return 1; } else { return 0; } } else { return 0; } } int main(void) { uint8_t data[2]; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); DHT11_Init(); while (1) { if (DHT11_ReadData(data)) { printf("Humidity: %d%%, Temperature: %d℃\r\n", data[0], data[1]); } else { printf("Read data error!\r\n"); } Delay_ms(2000); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值