引言:
腾讯举办的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一次通讯会传送40位数据,包含了温湿度数据和校验位,接下来是时序图:
这里只做简单介绍,网上资料很多,顺便贴上个网址:https://www.docin.com/p-2210836129.html
看时序图写代码:
上图是温湿度数据读取启动时序图,上图时序转代码思路如下:
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的时序图的低电平时间都是固定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的所有步骤,初次发文,诸多不足,大伙见谅哈,按照以上步骤没能成功的小伙伴可以留言讨论哈。