学习笔记9-DHT11

一、相关资料

  • DHT11数字温湿度传感器是含已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。
  • 建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使 用合适的上拉电阻
  • 单线制串行接口,即只有一根数据线,用于系统中的数据交换、控制。使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。

相关参数
在这里插入图片描述

典型电路
在这里插入图片描述
使用3.3V电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。

引脚说明
在这里插入图片描述

二、串行通信说明(单线双向)

2.1、数据格式

DHT11每次采集都要由单片机发起开始信号,然后DHT11会向单片机发送响应并开始传输40位数据帧,高位在前。
数据格式为:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。
在这里插入图片描述
以下是示例:

在这里插入图片描述

2.2、通讯过程

总时序图
在这里插入图片描述
MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据。

2.2.1、采集数据

总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。主机发送开始信号结束后,延时等待20-40us后, 开始读取DHT11的响应信号,切换为输入状态,等待DHT11的80us低电平信号结束,然后判断DHT11是否是否发出 80us 的高电平;如果是,即可开始采集数据。
在这里插入图片描述

2.2.2、数据0信号时序

当DHT11输出数字0时, 单片机读取到的信号为50 us的低电平,之后为26-28 us的高电平。
在这里插入图片描述

2.2.3、数字1信号时序

当DHT11输出数字1时, 单片机读取到的信号为50 us的低电平,之后为70 us的高电平。
在这里插入图片描述

可见,数字信号1和数字信号0的区别在于高电平时间不同。
可通过设置高电平阈值判断信号种类:单片机可在读取到高电平后,延时30us后,识别此时总线的电平,高电平为数字1,低电平为数字0。

三、代码

3.1、DHT11.c

// 配置为输入
void dth11_input(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);	 //使能PC,D,G端口时钟
	
	/*Configure GPIO pin : PtPin */
  GPIO_InitStruct.GPIO_Pin = DTH_IN_Pin;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//  GPIO_InitStruct.GPIO_Pull = GPIO_NOPULL;
  GPIO_Init(DTH_IN_GPIO_Port, &GPIO_InitStruct);
}
 
// 配置为输出
void dth11_output(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);	 //使能PC,D,G端口时钟
	
	/*Configure GPIO pin : PtPin */
  GPIO_InitStruct.GPIO_Pin = DTH_IN_Pin;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DTH_IN_GPIO_Port, &GPIO_InitStruct);
}
 
// 复位
void dth11_reset(void)
{
	dth11_output();
	DTH11_Clr();
	DelayMs(20);
	DTH11_Set();
	DelayUs(20);
	dth11_input();
}
 
// 读取一个bit数据
unsigned short dht11_read_bit(void)
{
	while(DTH11_IN == Bit_RESET);
	DelayUs(40);
	if(DTH11_IN == Bit_SET)
	{
		while(DTH11_IN == Bit_SET);
		return 1;
	}else {
		return 0;
	}
}
 
// 读取一个字节的数据
unsigned short dht11_read_byte(void)
{
	unsigned char i;
	unsigned short data = 0;
	for(i=0;i<8;i++)
	{
		data <<= 1;
		data |= dht11_read_bit();
	}
	return data;
}
 
// 读取数据
uint8_t dht11_read_data(DHT11_Data_TypeDef* DTH_Data)
{
	uint8_t checksum;
	uint16_t data_temp;
	
	dth11_reset(); // 复位
	if(DTH11_IN == Bit_RESET)
	{
		// 监测到DTH11响应
		while(DTH11_IN == Bit_RESET);
		while(DTH11_IN == Bit_SET);
		// 开始读取有效数据,一共五个字节
		DTH_Data->humi_high8bit = dht11_read_byte();
		DTH_Data->humi_low8bit = dht11_read_byte();
		DTH_Data->temp_high8bit = dht11_read_byte();
		DTH_Data->temp_low8bit = dht11_read_byte();
		DTH_Data->check_sum = dht11_read_byte();
		while(DTH11_IN == Bit_RESET);
		// 读取完毕,设置为输出
		dth11_output();
		DTH11_Set();
		/* 对数据进行处理 */
    data_temp=DTH_Data->humi_high8bit*100+DTH_Data->humi_low8bit;
    DTH_Data->humidity =(float)data_temp/100;
    
    data_temp=DTH_Data->temp_high8bit*100+DTH_Data->temp_low8bit;
    DTH_Data->temperature=(float)data_temp/100;   
		
		// 检验数据
		checksum = DTH_Data->humi_high8bit + DTH_Data->humi_low8bit + DTH_Data->temp_high8bit + DTH_Data->temp_low8bit;
		if(checksum != DTH_Data->check_sum){
			return ERROR;
		}else{
			return SUCCESS;
		} 
	}else {
		return ERROR;
	}
}

3.2、DHT11.h

typedef struct
{
	uint8_t  humi_high8bit;                //原始数据:湿度高8位
	uint8_t  humi_low8bit;                 //原始数据:湿度低8位
	uint8_t  temp_high8bit;                //原始数据:温度高8位
	uint8_t  temp_low8bit;                 //原始数据:温度高8位
	uint8_t  check_sum;                     //校验和
  float    humidity;        //实际湿度
  float    temperature;     //实际温度  
} DHT11_Data_TypeDef;
 
#define DTH_IN_Pin GPIO_Pin_6
#define DTH_IN_GPIO_Port GPIOE

#define DTH11_Clr() GPIO_ResetBits(DTH_IN_GPIO_Port, DTH_IN_Pin)
#define DTH11_Set() GPIO_SetBits(DTH_IN_GPIO_Port, DTH_IN_Pin)	 
#define DTH11_IN	GPIO_ReadInputDataBit(DTH_IN_GPIO_Port, DTH_IN_Pin)

3.3、main.c

void Displey_Temp()
{
	uint8_t res = dht11_read_data(&dth11_data);
	if(res == SUCCESS)
	{
		printf("humidity = %f \r\n",dth11_data.humidity);
		printf("temperature = %f \r\n",dth11_data.temperature);
		//LCD_ShowString(85,20,200,200,16,"humi = ");
		//LCD_ShowString(80,80,200,200,16,"humi = ");
		//LCD_ShowxNum(80,60,dth11_data.temperature,20,16,1);
		OLED_ShowString(0,0,"temp=");
		OLED_ShowNum(40,0,dth11_data.temp_high8bit/10,1,5) ;
		OLED_ShowNum(48,0,dth11_data.temp_high8bit%10,1,5) ;
		OLED_ShowString(56,0,".");
		OLED_ShowNum(64,0,dth11_data.temp_low8bit/10,1,5) ;
		OLED_ShowNum(72,0,dth11_data.temp_low8bit%10,1,5) ;
		OLED_ShowString(80,0,"°C");
		
		OLED_ShowString(0,2,"humi=");
		OLED_ShowNum(40,2,dth11_data.humi_high8bit/10+'0',1,5) ;
		OLED_ShowNum(48,2,dth11_data.humi_high8bit%10+'0',1,5) ;
		OLED_ShowString(56,2,".");
		OLED_ShowNum(64,2,dth11_data.humi_low8bit/10+'0',1,5) ;
		OLED_ShowNum(72,2,dth11_data.humi_low8bit%10+'0',1,5) ;
		OLED_ShowString(80,2,"RH");
		DelayS(1);
	}
	else{
 		printf("read ERROR ! \r\n");
//		OLED_Show_String(0,4,"Read Error !!",BIG);
 		OLED_ShowString(0,5,"Read Error");
	}
}

小疑问
还没有想清楚为什么用Displey_Temp()函数时OLED屏幕会显示正常的温湿度但也会显示“Read Error”。

参考自:
1、单片机——DHT11 温湿度传感器
2、dht11 新手原理详解(附代码)


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
elui-china-area-dht是一个组件,用于选择中国的省、市、区县信息。根据引用\[1\]和引用\[2\]的代码,可以看出elui-china-area-dht组件被引入并使用了。在代码中,通过监听change事件,可以获取到选择的省、市、区县的值,并进行相应的操作。在引用\[1\]的代码中,onChange函数中的参数e是一个数组,数组的每个元素对应着选择的省、市、区县的索引值,通过这些索引值可以从chinaData中获取到对应的省、市、区县信息。在引用\[2\]的代码中,onChange函数中的参数e是一个数字,通过这个数字可以直接从chinaData中获取到对应的省、市信息。所以,根据不同的代码实现,可以选择不同的方式来获取elui-china-area-dht组件选择之后的参数取值。 #### 引用[.reference_title] - *1* [基于vue3.2的element-plus省市区选择器](https://blog.csdn.net/m0_60459392/article/details/127638885)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [基于vue3和element-plus的省市区级联组件,elui-china-area-dht发布](https://blog.csdn.net/qq_32858649/article/details/112221640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ChristianLuu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值