这说讲一下DHT11驱动,一共有3个引脚分别是VCC , GND , DATA。
使用起来也是非常的简单,手册里有非常详细的时序图(还是中文的)。
步骤一:
DHT11上电后(DHT11上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境温湿度数据,并记录数据,同时 DHT11的DATA数据线由上拉电阻拉高一直保持高电平;此时 DHT11的 DATA 引脚处于输入状态,时刻检测外部信号。
步骤二:
微处理器的I/O设置为输出同时输出低电平,且低电平保持时间不能小于18ms,然后微处理器的I/O设置为输入状态,由于上拉电阻,微处理器的I/O即DHT11的DATA数据线也随之变高,等待DHT11作出回答信号,发送信号如图所示:
步骤三:
DHT11的DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后DHT11的DATA引脚处于输出状态,输出 80微秒的低电平作为应答信号,紧接着输出 80 微秒的高电平通知外设准备接收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11回应信号)后,等待80微秒的高电平后的数据接收,发送信号如图所示:
步骤四:
由DHT11的DATA引脚输出40位数据,微处理器根据I/O电平的变化接收40位数据,位数据“0”的格式为: 50 微秒的低电平和 26-28 微秒的高电平,位数据“1”的格式为: 50 微秒的低电平加70微秒的高电平。位数据“0”、“1”格式信号如图所示:
结束信号:
DHT11的DATA引脚输出40位数据后,继续输出低电平50微秒后转为输入状态,由于上拉电阻随之变为高电平。但DHT11内部重测环境温湿度数据,并记录数据,等待外部信号的到来。
以上就是整体的时序操作方法,还要多说一句就是DHT11对是需要求很严格,我最开始怎么调也出不来数据,最后经过网友的博客才想起中断影响时间延时的问题,因此需要屏蔽掉中断在进行操作,就没有问题了。
驱动是直接用我以前写的18b20改的,因此里面有一些忘记改的名称或函数,说明一下不要被迷惑。
/*基本linux头文件,用于定义驱动函数进出口与协议*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>
/*inux中申请GPIO的头文件*/
#include <linux/gpio.h>
/*三星平台的GPIO配置函数头文件*/
/*三星平台EXYNOS系列平台,GPIO配置参数宏定义头文件*/
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
/*三星平台4412平台,GPIO宏定义头文件*/
#include <mach/gpio-exynos4.h>
#include <asm/uaccess.h>
/*在平台文件中定义的宏里name的命名*/
#define DRIVER_NAME "18b20_train"
#define DEVICE_NAME "ds18b20_train"
/*1,GPL协议,2,作者名*/
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("C.L.");
static int DHT11_gpios[] = {EXYNOS4_GPX0(1),EXYNOS4212_GPJ1(0)};
static int chose = 0;
unsigned char buff_data[6];
unsigned char check_flag;
#define DHT11_NUM ARRAY_SIZE(DHT11_gpios)
/*io口控制,接受由上层传递的数据cmd、arg*/
#define Delay_us(x) udelay(x)
#define Delay_ms(x) mdelay(x)
/* #define SetDS18B20IOout() s3c_gpio_cfgpin(DHT11_gpios[0], S3C_GPIO_OUTPUT)
#define SetDS18B20IOin() s3c_gpio_cfgpin(DHT11_gpios[0], S3C_GPIO_INPUT)
#define WriteDS18B20IO(data) gpio_set_value(DHT11_gpios[0], data)
#define ReadDS18B20IO() gpio_get_value(DHT11_gpios[0]) */
void SetDS18B20IOout(void){
s3c_gpio_cfgpin(DHT11_gpios[chose], S3C_GPIO_OUTPUT);
}
void SetDS18B20IOin(void){
s3c_gpio_cfgpin(DHT11_gpios[chose], S3C_GPIO_INPUT);
}
void WriteDS18B20IO(int data){
gpio_set_value(DHT11_gpios[chose], data);
}
int ReadDS18B20IO(void){
return (gpio_get_value(DHT11_gpios[chose]));
}
static unsigned char DHT11ReadByte(void)
{
int time,i;
unsigned char data;
unsigned char flag;
data = 0x0;
flag = 0x0;
for (i = 0; i < 8; i++)
{
time = 0;
while(!ReadDS18B20IO())
{
time++;
if (time >20)
{
return -1;
printk("Read error1!\n");
}
udelay(5);
}
udelay(30);
flag=0x0;
if(ReadDS18B20IO())
{
flag=0x01;
}
time = 0;
while(ReadDS18B20IO())
{
time++;
if (time > 100)
{