STM32CubeMX之温湿度传感器DHT11

        DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃,最远可测得20m以内得温湿度。

        DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测型号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用甚至最为苛刻的应用场合的最佳选择。

2599dd3d5a324581878a04d3c4ec8614.png

08d1e423bdce49b0802d21a9be61ef8e.png 

根据在这个通信协议进行通信。 

下面进行端口的配置

ef6ec6e1dd4d45928ebf8031f95c5838.png

 然后编写DHT11.c和DHT11.h文件

DHT11.c

#include "dht11.h"
#include "main.h"

void DHT11_IO_OUT (void){ //端口变为输出
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = DHT11_DA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_IO_IN (void){ //端口变为输入
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = DHT11_DA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
	DHT11_IO_OUT();
	HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_RESET);
	HAL_Delay(20); //拉低至少18ms
	HAL_GPIO_WritePin(GPIOB,DHT11_DA_Pin, GPIO_PIN_SET);
	delay_us(30); //主机拉高20~40us
}

uint8_t Dht11_Check(void){ //等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)
	uint8_t retry=0;
    DHT11_IO_IN();//IO到输入状态
    while (HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11会拉低40~80us
        retry++;
        delay_us(1);
    }
    if(retry>=100)return 1; else retry=0;
    while (!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//DHT11拉低后会再次拉高40~80us
        retry++;
        delay_us(1);
    }
    if(retry>=100)return 1;
    return 0;
}

uint8_t Dht11_ReadBit(void){ //从DHT11读取一个位 返回值:1/0
	uint8_t retry=0;
    while(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变为低电平
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin)&&retry<100){//等待变高电平
        retry++;
        delay_us(1);
    }
    delay_us(40);//等待40us	//用于判断高低电平,即数据1或0
    if(HAL_GPIO_ReadPin(GPIOB,DHT11_DA_Pin))return 1; else return 0;
}

uint8_t Dht11_ReadByte(void){  //从DHT11读取一个字节  返回值:读到的数据
	uint8_t i,dat;
    dat=0;
    for (i=0;i<8;i++){
        dat<<=1;
        dat|=Dht11_ReadBit();
    }
    return dat;
}

uint8_t DHT11_Init (void){	//DHT11初始化
	DHT11_RST();//DHT11端口复位,发出起始信号
	return Dht11_Check(); //等待DHT11回应
}

uint8_t DHT11_ReadData(uint8_t *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败
	uint8_t buf[5];
	uint8_t i;
    DHT11_RST();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            *h=buf[0]; //将湿度值放入指针1
			h++;
            *h=buf[2]; //将温度值放入指针2
        }
    }else return 1;
    return 0;
}

DHT11.h

#ifndef DHT11_DHT11_H_
#define DHT11_DHT11_H_

#include "stm32f1xx_hal.h"
#include "../delay/delay.h"

void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init (void);
uint8_t DHT11_ReadData(uint8_t *h);


#endif /* DHT11_DHT11_H_ */

然后在主程序中,调用头文件,并在main.c中进行操作

b89076230e6c4007adc97d37fe77e573.png

 这里的初始化需要进行传感器的第一次数据获取53ff054c523f41aaaf4a19ea34f59217.png

ec374e09ffdf45c58e0a09e2ad049e55.png

 最后打开串口,就可以查看到数据的传输了。

总结:

        当第一次做这些的时候,看见单总线协议自己如果不知道怎么写,就去网上查询,看别人怎么写的,在进行协议的修改。

 

  • 2
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
您好!对于使用STM32F1HAL驱动DHT11湿度传感器,您可以按照以下步骤进行操作: 1. 首先,您需要确保已经正确连接了DHT11传感器到STM32F1开发板上。将DHT11的VCC引脚连接到STM32F1的3.3V电源引脚,将GND引脚连接到STM32F1的地引脚,将DHT11的数据引脚连接到STM32F1的GPIO引脚。 2. 在STM32CubeMX中配置相关的GPIO引脚。选择合适的GPIO引脚作为DHT11传感器的数据引脚,并设置为输入模式。 3. 在代码中初始化相关的GPIO引脚,以及使用HAL库中的延时函数。 4. 编写代码读取DHT11传感器的数据。您可以使用GPIO读取数据引脚的电平变化来读取温湿度数据。具体的读取过程可以参考DHT11的通信协议。 下面是一个简单的示例代码,用于读取DHT11传感器的温湿度数据: ```c #include "stm32f1xx_hal.h" #define DHT11_PORT GPIOA #define DHT11_PIN GPIO_PIN_0 void delay_us(uint32_t us) { us *= (SystemCoreClock / 1000000) / 9; while (us--) { __NOP(); } } void DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = DHT11_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct); } void DHT11_Read(uint8_t *humidity, uint8_t *temperature) { uint8_t data[5] = {0}; uint8_t i, j; // 主机拉低总线,持续18ms以上 HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET); delay_us(20000); // 主机释放总线,并等待DHT11响应 HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET); delay_us(30); if (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET) { // 等待DHT11拉低总线,持续80us while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET); // 等待DHT11拉高总线,持续80us while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET); // 接收温湿度数据 for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { // 等待DHT11拉低总线,持续50us while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET); // 计算数据位 delay_us(30); if (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET) { data[i] |= (1 << (7 - j)); } // 等待DHT11拉高总线,持续26-28us或70us while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET); } } // 校验数据 if ((data[0] + data[1] + data[2] + data[3]) == data[4]) { *humidity = data[0]; *temperature = data[2]; } } } int main(void) { uint8_t humidity, temperature; HAL_Init(); DHT11_Init(); while (1) { DHT11_Read(&humidity, &temperature); // 处理温湿度数据 // ... } } ``` 请注意,这只是一个简单的示例代码,您可能需要根据实际情况进行适当的修改和调整。此外,为了保证准确性,您可能需要添加适当的校验和错误处理机制。 希望这能帮助到您!如果您有任何进一步的问题,请随时提问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啵啵520520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值