stm32之DHT11

今天,记录一下DHT11,涉及到了单总线协议,所以先花点时间谈论一下单总线协议(DS18B20也是用的单总线)。

单总线协议

单总线技术的通信协议

可能这时序图就是个例子,ds18b20的时序图与DHT11的时序图也是不一样的。

DHT11

复制代码
#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"                  // Device header

#define DHT11_PORT 			GPIOC   
#define DHT11_PIN 			GPIO_Pin_10
#define DHT11_PORT_RCC		RCC_APB2Periph_GPIOC

#define dht11_high GPIO_SetBits(GPIOC, GPIO_Pin_10)
#define dht11_low GPIO_ResetBits(GPIOC, GPIO_Pin_10)
#define Read_Data GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_10)

void DHT11_GPIO_Init_OUT(void);
void DHT11_GPIO_Init_IN(void);
void DHT11_Start(void);
unsigned char DHT11_REC_Byte(void);
void DHT11_REC_Data(void);


#endif

#include "stm32f10x.h"                  // Device header
#include  "dht11.h"
#include  "SysTick.h"
//数据
unsigned int rec_data[4];


//对于stm32来说,是输出
void DH11_GPIO_Init_OUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOC, &GPIO_InitStructure);

}

//对于stm32来说,是输入
void DH11_GPIO_Init_IN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOC, &GPIO_InitStructure);

}


//主机发送开始信号
void DHT11_Start(void)
{
	DH11_GPIO_Init_OUT(); //输出模式
	
	dht11_high; //先拉高
	delay_us(30);
	
	dht11_low; //拉低电平至少18us
	delay_ms(20);
	
	dht11_high; //拉高电平20~40us
	delay_us(30);
	
	DH11_GPIO_Init_IN(); //输入模式,可以说是释放总线
}


//获取一个字节
char DHT11_Rec_Byte(void)
{
	unsigned char i = 0;
	unsigned char data;
	
	for(i=0;i<8;i++) //1个数据就是1个字节byte,1个字节byte有8位bit
	{
		while( Read_Data == 0); //从1bit开始,低电平变高电平,等待低电平结束
		delay_us(30); //延迟30us是为了区别数据0和数据1,0只有26~28us
		
		data <<= 1; //左移
		
		if( Read_Data == 1 ) //如果过了30us还是高电平的话就是数据1
		{
			data |= 1; //数据+1
		}
		
		while( Read_Data == 1 ); //高电平变低电平,等待高电平结束
	}
	
	return data;
}

//获取数据

void DHT11_REC_Data(void)
{
	unsigned int R_H,R_L,T_H,T_L;
	unsigned char RH,RL,TH,TL,CHECK;
	
	DHT11_Start(); //主机发送信号
	dht11_high; //拉高电平
	
	if( Read_Data == 0 ) //判断DHT11是否响应
	{
		while( Read_Data == 0); //低电平变高电平,等待低电平结束
		while( Read_Data == 1); //高电平变低电平,等待高电平结束,耗费掉DHT11的响应输出
		
		R_H = DHT11_Rec_Byte();
		R_L = DHT11_Rec_Byte();
		T_H = DHT11_Rec_Byte();
		T_L = DHT11_Rec_Byte();
		CHECK = DHT11_Rec_Byte(); //接收5个数据
		
		dht11_low; //当最后一bit数据传送完毕后,DHT11拉低总线 50us
		delay_us(55); //这里延时55us
		dht11_high; //随后总线由上拉电阻拉高进入空闲状态。
		
		if(R_H + R_L + T_H + T_L == CHECK) //和检验位对比,判断校验接收到的数据是否正确
		{
			RH = R_H;
			RL = R_L;
			TH = T_H;
			TL = T_L;
		}
	}
	rec_data[0] = RH;
	rec_data[1] = RL;
	rec_data[2] = TH;
	rec_data[3] = TL;
}

像DHT11响应输出,以及DHT11输出的0和1,这些是DHT11内部的控制器发出来的,我们不需要写时序去描述,只需要对DHT11输出的数据进行读取,判断即可
附录:
DHT11详细介绍(内含51和STM32代码)_安赫'的博客-CSDN博客
七、【中级篇】传感器DHT11、DHT22、DS18B20_dht22和dht11比较_十七阿哥的春天的博客-CSDN博客
16 STM32基础学习 DS18B20 温度与DHT11温湿度模块 - 古月居 (guyuehome.com)
【通信协议】1-Wire 单总线_淹死的大白鲨的博客-CSDN博客
DHT11 温湿度传感器_比特冬哥的博客-CSDN博客

相关推荐
小李不困还能学23 分钟前
基于 51 单片机的8 路抢答器设计教程
单片机·嵌入式硬件·mongodb·抢答器
萌动的小火苗1 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
振浩微433射频芯片2 小时前
工业遥控器总在关键时刻“掉链子”?——433MHz芯片方案如何破局
网络·单片机·嵌入式硬件·物联网·工业遥控
blevoice2 小时前
抖抖燃脂机单 AC6966B 主控调试踩坑:Type-C 整机供电喇叭无声排障
c语言·开发语言·单片机
三易串口屏3 小时前
三易串口屏开发教程:如何使用键盘控件输入参数并发送给单片机
单片机·嵌入式硬件·串口屏·三易串口屏·键盘控件
十月的皮皮4 小时前
STM32从零到量产开发:四路继电器工业控制模块开发实战笔记(小白视角)
c语言·笔记·stm32·stm32cubemx·hal库
2CM_Embed4 小时前
F28379D 下载后 VOFA+ 无数据、Reset 后恢复:一次 TZ 中断误触发排查记录
笔记·单片机·sci·c2000·f28379d·vofa·tz
国科安芯4 小时前
空间机电一体化:AS32S601型抗辐射MCU在卫星推进与执行机构控制中的关键技术研究
单片机·嵌入式硬件·物联网·机器人·云计算
国科安芯5 小时前
AS32S601型抗辐射MCU在分布式太空算力架构中的技术演进与应用前景
人工智能·分布式·单片机·嵌入式硬件·架构·边缘计算
国科安芯5 小时前
在轨能源中枢:AS32S601型抗辐射MCU在卫星电源管理与配电系统中的控制策略研究
嵌入式硬件·架构·能源·risc-v·sps·电源管理·卫星