内核: vi drivers/char/dht11.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <asm-generic/errno-base.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio.h>
#include <linux/delay.h>
#define DEV_NAME "dht11"
#define PIN_DHT11 S3C2410_GPF(6)
static void pin_init(void)
{
gpio_request(PIN_DHT11, "dht11");
}
static void dht11_start(void)
{
gpio_direction_output(PIN_DHT11, 0);
mdelay(20);
gpio_set_value(PIN_DHT11, 1);
udelay(30);
gpio_direction_input(PIN_DHT11);
}
static int dht11_wait_repon(void)
{
int time = 100;
while(gpio_get_value(PIN_DHT11)) // wait H end
{
udelay(1);
if(!time--)
return -1;
}
time = 100;
while(!gpio_get_value(PIN_DHT11) && time) // wait 80us L end
{
udelay(1);
if(!time--)
return -2;
}
time = 100;
while(gpio_get_value(PIN_DHT11)) // wait 80us H end
{
udelay(1);
if(!time--)
return -3;
}
return 0;
}
static int dht11_get_bit(void)
{
int time = 100;
while(!gpio_get_value(PIN_DHT11)) // wait 50us L end
{
udelay(1);
if(!time--)
return -1;
}
udelay(30);
if(0 == gpio_get_value(PIN_DHT11))
return 0;
while(gpio_get_value(PIN_DHT11)) // wait 40us H end
{
udelay(1);
if(!time--)
return -2;
}
return 1;
}
static int dht11_get_value(unsigned char * data)
{
int i = 0;
int j = 0;
unsigned char sum = 0;
for(i = 0; i < 5; i++)
{
data[i] = 0;
for(j = 0; j < 8; j++)
{
char bit = dht11_get_bit();
if(bit < 0)
return bit;
data[i] <<= 1;
data[i] |= bit;
}
}
for(i = 0; i < 4; i++)
{
sum += data[i];
}
if(sum == data[4])
return 4;
else
return -1;
}
static int open (struct inode * inode, struct file * file)
{
pin_init();
printk("dht11 open ...\n");
return 0;
}
static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{
unsigned char data[4] = {0};
int ret = 0;
dht11_start();
ret = dht11_wait_repon();
if(ret < 0)
goto err_wait;
ret = dht11_get_value(data);
if(ret < 0)
goto err;
copy_to_user(buf, &data, sizeof(data));
printk("dht11 read ...\n");
return sizeof(data);
err_wait:
printk("dht11_wait_repon err ... \n");
return ret;
err:
printk("dht11_get_value err ...\n");
return ret;
}
static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{
return 0;
}
static int close (struct inode * inode, struct file * file)
{
printk("dht11 close ...\n");
return 0;
}
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = open,
.read = read,
.write = write,
.release = close
};
static struct miscdevice misc =
{
.minor = MISC_DYNAMIC_MINOR,
.name = DEV_NAME,
.fops = &fops
};
static int __init dht11_init(void)
{
int ret = misc_register(&misc);
if(ret < 0)
goto err_misc_register;
printk("dht11_init ...\n");
return ret;
err_misc_register:
misc_deregister(&misc);
printk("dht11 misc_register faidht11\n");
return ret;
}
static void __exit dht11_exit(void)
{
misc_deregister(&misc);
printk("dht11_exit ###############################\n");
}
module_init(dht11_init);
module_exit(dht11_exit);
MODULE_LICENSE("GPL");
应用层:~/nfs/rootfs$ vi dht11_app.c
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, const char *argv[])
{
int fd = open("/dev/dht11",O_RDWR);
if(fd < 0 )
{
perror("open dht11");
return -1;
}
while(1)
{
unsigned char data[4] = {0};
int ret = read(fd,data,sizeof(data));
printf("ret = %d\n",ret);
int i = 0;
for(i = 0; i < 4; ++i)
{
printf("%x\t",data[i]);
}
printf("\n");
sleep(2);
}
close(fd);
return 0;
}