关于DHT11的数据获取(STM32F030,基于LL库,内有超详细代码)

关于DHT11的数据获取

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数
字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一
个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。(摘自官方的描述)

废话不多说,直接看时序图

整体介绍,
在这里插入图片描述
当一次开始之后,DHT11会发生40bit的信号,一共5个字节,计算方式如下
在这里插入图片描述
外设读取步骤
步骤一:
DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境
温湿度数据,并记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的
DATA 引脚处于输入状态,时刻检测外部信号。

步骤二:
微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms),
然后微处理器的 I/O 设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变
高,等待 DHT11 作出回答信号,发送信号如图所示:
在这里插入图片描述
(摘自官方的描述)
步骤三:
DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA
引脚处于输出状态,输出 83 微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接
收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 87 微秒
的高电平后的数据接收,发送信号如图所示:
在这里插入图片描述
(摘自官方的描述)

/*在这里我将步骤二和步骤三写在一起了*/

static void usDelay(uint8_t x)                                          //毫秒延迟,我开了一个定时器,但是我没有开中断,会有一点误差,但是不会太大
{
	LL_TIM_DisableCounter(TIM1);
	LL_TIM_SetCounter(TIM1, 0);
	LL_TIM_EnableCounter(TIM1);
	while (LL_TIM_GetCounter(TIM1) != x)
	{
	}
}

static uint8_t SetDHT11(void)
{
	uint8_t wait = 0;
	
	LL_GPIO_SetPinMode(GPIOB,LL_GPIO_PIN_1,LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetPinOutputType(GPIOB,LL_GPIO_PIN_1,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_1);
	LL_mDelay(19);                                                                       //根据描述,拉低大于18MS
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_1);
	usDelay(30);                                                                          //释放总线

	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_1, LL_GPIO_MODE_INPUT);
	LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_1, LL_GPIO_OUTPUT_OPENDRAIN);
	LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_1, LL_GPIO_PULL_UP);                              //将引脚置为输入

	while ((!LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1)) && (wait < 100))
	{
		wait++;
		usDelay(1);
	}
	if (wait > 99)
		return 0;
	else                                                                                                       //判断是否有83us的低电平,考虑到各方面的误差,我放到了<99
	{
		wait = 0;
		while ((LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1)) && (wait < 100))
		{
			usDelay(1);
			wait++;
		}
		if (wait > 99)                                        //判断是否有87us的高电平,考虑到各方面的误差,我放到了<99
		{
			wait = 0;
			return 0;
		}
		else
			return 1;
	}
}

步骤四:
由 DHT11 的 DATA 引脚输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据,位数据“0”
的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加 68-74
微秒的高电平。位数据“0”、“1”格式信号如图所示:
在这里插入图片描述
(摘自官方的描述)

/*在这里我做了整合,直接得到一个字节的数据*/
static uint8_t ReadDHT11_Byte(void)
{
	uint8_t wait;
	uint8_t value_bit;
	uint8_t value;
	
	for (uint8_t n = 0; n < 8; n++)
	{
		if (!LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1))
		{
			while (!LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1) && (wait < 65))
			{
				wait++;
				usDelay(1);
			}                                                             //等待共同的低电平
			wait = 0;p
			usDelay(40);                                                                           //判断下一个时刻的电平
			if (LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1))
				value_bit = 1;                                                                 //都>27us了一定为1
			else
				value_bit = 0;                                
			value <<= 1;                                                                  //移位
			value |= value_bit;
			while (LL_GPIO_IsInputPinSet(GPIOB, LL_GPIO_PIN_1) && (wait < 27))                          //等待剩下的高电平
			{
				wait++;
				usDelay(1);
			}
		}
	}
	
	return value;
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值