内核驱动)"/>
温湿度传感器DHT11数据手册详解(Linux内核驱动)
一、引脚说明
二、时序解读
2.1、通信过程
2.2、开始信号
主机发送一个大于18ms的低电平给DHT11作为启动信号。
然后拉高20-40us后读DHT11响应信号。
发开始信号
DHT11_IO_OUT(); //SET OUTPUTDHT11_OUT_LOW(); //拉低DQdelay_ms(5); //拉低至少18msdelay_ms(5);delay_ms(5);delay_ms(5);DHT11_OUT_HIGH(); //DQ=1 delay_us(30); //主机拉高20~40us
2.3、响应信号
DHT11检测到开始信号后,会等待开始信号结束,然后发送响应信号。
响应信号为一个80us的低电平。
响应信号发送后,会拉高80us,然后发送数据。
读响应信号
DHT11_IO_IN();//SET INPUT while (DHT11_IN_LEVEL() == 0 && retry<100)//DHT11会拉低80us{retry++;delay_us(1);}; if(retry>=100)return 0;else retry=0;
2.4、一位数据的表示
一个位数据总是从50us的低电平开始,高电平持续时间不同表示0和1
2.4.1、数字0信号
高电平持续26-28us表示0
2.4.2、数字1信号
高电平持续70us表示0
2.4.3、读取一位数据
低电平结束后,延时大于28us(小于28+50us,要在下一个高电平来之前读取数据),主机读取当前电平,读到高电平表示DHT11发送数据1,读到低电平表示DHT11发送数据0。
while(DHT11_IN_LEVEL())//等待变为低电平{}while(!DHT11_IN_LEVEL())//等待变高电平{}delay_us(40);//等待40usreturn DHT11_IN_LEVEL();
三、树莓派4B内核驱动代码(部分代码)
使用GPIO25
#define delay_us(x) udelay(x);
#define delay_ms(x) mdelay(x);#define DHT11_IO_OUT() *GPFSEL2 &= ~(0x6 << 15);\*GPFSEL2 |= (0x1 << 15);#define DHT11_IO_IN() *GPFSEL2 &= ~(0x7 << 15);\*GPFSEL2 |= (0x0 << 15); #define DHT11_OUT_HIGH() *GPSET0 = 1 << 25;
#define DHT11_OUT_LOW() *GPCLR0 = 1 << 25; #define DHT11_IN_LEVEL() ((*GPLEV0>>25) & 1)static unsigned char DHT11_Read_Bit(void)
{while(DHT11_IN_LEVEL())//等待变为低电平{}while(!DHT11_IN_LEVEL())//等待变高电平{}delay_us(40);//等待40usreturn DHT11_IN_LEVEL();
}//从DHT11读取一个字节
static unsigned char DHT11_Read_Byte(void)
{ unsigned char i,dat;dat=0;for (i=0;i<8;i++) {dat<<=1; dat|=DHT11_Read_Bit();} return dat;
}static unsigned char DHT11_Read_Data(unsigned char *temp,unsigned char *humi)
{ unsigned char buf[5];unsigned char i;unsigned char retry=0;DHT11_IO_OUT(); //SET OUTPUTDHT11_OUT_LOW(); //拉低DQdelay_ms(5); //拉低至少18msdelay_ms(5);delay_ms(5);delay_ms(5);DHT11_OUT_HIGH(); //DQ=1 delay_us(30); //主机拉高20~40usDHT11_IO_IN();//SET INPUT while (DHT11_IN_LEVEL() == 0 && retry<100)//DHT11会拉低80us{retry++;delay_us(1);}; if(retry>=100)return 0;else retry=0;if(retry==0){for(i=0;i<5;i++)//读取40位数据{buf[i]=DHT11_Read_Byte();}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humi=buf[0];*temp=buf[2];}}else return 0;return 1;
}
四、测试代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main()
{char data[2];int nread = 0;int fd = open("/dev/dht11",O_RDWR);if(fd == -1){perror("open ");exit(-1);}while(1){getchar();nread = read(fd,data,2);printf("nread :%d temp=%d humi=%d\n",nread,data[0],data[1]);}}
DHT11 Linux内核驱动完整代码(树莓派4B)
更多推荐
温湿度传感器DHT11数据手册详解(Linux内核驱动)
发布评论