AIoT应用创新大赛-基于i.MX RT1062 SDK的DHT22温湿度传感器驱动程序

2022-01-18 23:10:51 浏览数 (1)

引言:

腾讯举办的AIoT应用创新大赛也开始有一个月时间了,大伙们都该入门的入门了,该折腾IDE的各种倒腾,这个用不习惯就换另一个。也有部分人平时工作,没啥时间瞎捣鼓的,比如我,我就直接用官方的IDE,不顺手,但是能用,省事是比较重要的。那么接下来我就记录一下,基于i.MX RT1062 SDK的温湿度传感器的软件驱动实现过程(官方IDE版本)。

DHT22温湿度传感器简介:

该传感器主要由一个电容式感湿元件和一个NTC测温元件组成,采用单总线通讯,只需要给传感器供电,用mcu的一个IO就能实现温湿度的读取了,非常的简单易用。但这并不代表该传感器不怎么样,在测量精度上,有着不凡的表现,参数如下:

DHT22技术参数:

1、湿度测量范围:0---100%RH

2、湿度测量精度:±2%RH

3、温度测量范围:-40---80℃

4、温度测量精度:±0.5℃

5、工作电压:DC3.3V ~ 5V

6、单总线数字信号输出,串口数据双向口;

DHT22通讯时序简单介绍:

要想驱动DHT22,就要先了解其通讯协议还有通讯时序,通讯数据协议如下:

DHT22通讯协议DHT22通讯协议

通过上图我们知道DHT22一次通讯会传送40位数据,包含了温湿度数据和校验位,接下来是时序图:

DHT22时序图DHT22时序图

这里只做简单介绍,网上资料很多,顺便贴上个网址:https://www.docin.com/p-2210836129.html

看时序图写代码:

DHT22启动数据读取时序DHT22启动数据读取时序

上图是温湿度数据读取启动时序图,上图时序转代码思路如下:

1.设置设备IO为输出模式,将IO拉高500ms(这个时间没有严格要求,不要太短就行);

2.然后将IO拉低1ms(0.8~20ms都可以)。

3.释放总线,将IO拉高50us(20~200us都可以);

4.然后将IO设置为输入模式,等待DHT22拉低数据线应答;

5.判断IO被拉低后,继续等待DHT22将数据线拉高;

6.数据线被拉高后,继续等待DHT22将数据线拉低;

通过以上6点完成是启动时序的步骤,接下来就是40位数据的读取了。下图为数据0和数据1的时序图:

数据0和数据1的时序图数据0和数据1的时序图

从图中可以看出,数据0和数据1的时序图的低电平时间都是固定50us,只有高电平的时间不一样,高电平时间短的为0,高电平时间长的为1,所以我们只要判断高电平的时间就能知道该位数据是0还是1了。接着上面的6个步骤:

7.等待数据线被拉高后,延时35us,读取当前IO电平,如果是低电平,则该位数据为0,反之为1;

8.每次都是在低电平变高电平的时候开始延时35us,循环40次便可得到传感器的数据;

9.读取完数据后将数据线设置为输出模式,并拉高IO,完成本次数据读取,每次数据读取间隔最好不低于2s;

通过上面的思路,将其转化为代码,如下:

代码语言:javascript复制
#define DHT22_GPIO	GPIO3
#define DHT22_PIN	17U
#define DHT22_PIN_OUT() 	gpio_set_dir(DHT22_GPIO, DHT22_PIN, kGPIO_DigitalOutput)
#define DHT22_PIN_IN() 	    gpio_set_dir(DHT22_GPIO, DHT22_PIN, kGPIO_DigitalInput)
#define DHT22_PIN_HIGH()	GPIO_PinWrite(DHT22_GPIO, DHT22_PIN, 1U)
#define DHT22_PIN_LOW()		GPIO_PinWrite(DHT22_GPIO, DHT22_PIN, 0U)
#define DHT22_PIN_READ()	GPIO_PinRead(DHT22_GPIO, DHT22_PIN)
#define DHT22_DELAY_US(x)	SDK_DelayAtLeastUs(x, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY)
#define DHT22_DELAY_MS(x)	SDK_DelayAtLeastUs(1000*x, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY)
uint8_t buff[5] = {0};
int humidity=0;
int temperature=0;
void DHT22_read()
{
	int i,j;
	uint8_t bit=0;
	uint8_t temp=0;

	DHT22_PIN_OUT(); //SET PA0 OUTPUT
	DHT22_PIN_HIGH(); //拉高
	DHT22_DELAY_MS(100);
	DHT22_PIN_LOW();
	DHT22_DELAY_US(1000);    //拉低1000us
    DHT22_PIN_HIGH(); //DQ=1
    DHT22_DELAY_US(50);     //50US
	DHT22_PIN_IN();
	while(DHT22_PIN_READ())
	{
		DHT22_DELAY_US(1);
	}
	while(!DHT22_PIN_READ())
	{
		DHT22_DELAY_US(1);
	}
	while(DHT22_PIN_READ())
	{
		DHT22_DELAY_US(1);
	}

	for(i=0; i<5; i  )
	{
		temp = 0;
		for(j=0; j<8; j  )
		{
			while(!DHT22_PIN_READ())
			{
				DHT22_DELAY_US(1);
			}
			DHT22_DELAY_US(35);
			if(DHT22_PIN_READ())
			{
				bit = 1;
				while(DHT22_PIN_READ())
				{
					DHT22_DELAY_US(1);
				}
			}else
			{
				bit = 0;
			}
			temp <<= 1;
			temp |= bit;
		}
		buff[i] = temp;
	}
	humidity = buff[0]<<8|buff[1];
	temperature = buff[2]<<8|buff[3];
}

代码中,我用到的是RT1062的GPIO3,如果是IO口不对,可以在IDE的管脚配置中修改管脚,下面在官方GPIO例程中简单举例一下:

1.选择IDE右上角芯片图标;

2.找到你想要的端口,比如上面代码的GPIO3,然后点击管脚坐标的选项框,会出现一下窗口;

3.然后我们选择上图圈起来的选项,将该管脚复用为普通IO模式;

4.然后你就会看到你配置好的管脚出现下方的配置栏中,如下图:

5.更新代码,即可,如图:

以上就是读取DHT22的所有步骤,初次发文,诸多不足,大伙见谅哈,按照以上步骤没能成功的小伙伴可以留言讨论哈。

0 人点赞