Android DHT11驱动


struct dht11_sensor_dev{struct cdev cdev;unsigned long pin;unsigned char value[5];unsigned char lock;unsigned int irq;struct timeval lasttv;int bitcount;int bytecount;int started;struct timer_list timer;void (*write_bit)(unsigned long pin, char bit);void (*delay)(short t);};static struct dht11_sensor_dev *dht11_dev;struct class *dht11_class;static int major = DEVICE_MAJOR;static inline void usdelay(short t){return ndelay(t * 1000);}static inline void gpio_write_bit(unsigned long pin, char bit){gpio_set_value(pin, bit);}#if 0static char gpio_read_bit(unsigned long pin){return gpio_get_value(pin) ? 1 : 0;//return gpio_get_value(pin);}static void gpio_write_bit_dir(unsigned long pin, char bit){if (bit)gpio_direction_input(pin);elsegpio_direction_output(pin, 0);}static void gpio_write_bit_val(unsigned long pin, char bit){gpio_set_value(pin, bit);}static int dht11_get_temperature(struct dht11_sensor_dev *dev){return dev->value[0] * 1000 + dev->value[1];}static int dht11_get_humidity(struct dht11_sensor_dev *dev){return dev->value[2] * 1000 + dev->value[3];}#endifstatic irqreturn_t dht11_interrupt(int irq, void *dev_id){struct dht11_sensor_dev *dev = (struct dht11_sensor_dev *)dev_id;struct timeval tv;long deltv = 0;int signal = 0, data = 0;signal = gpio_get_value(dev->pin);do_gettimeofday(&tv);deltv = tv.tv_sec - dev->lasttv.tv_sec;data = (int)(deltv * 1000000 + (tv.tv_usec - dev->lasttv.tv_usec)); dev->lasttv = tv;if(dev->bytecount == 5) return IRQ_HANDLED;if((signal == 1) & (data > 40)){dev->started = 1;return IRQ_HANDLED;}if((signal == 0) & (dev->started == 1)){if(data > 80)return IRQ_HANDLED;if(data < 30){dev->bitcount++;if(dev->bitcount == 8){dev->bitcount = 0;dev->bytecount++;}return IRQ_HANDLED;}if (data > 60)//55 dev->value[dev->bytecount] = dev->value[dev->bytecount] | (0x80 >> dev->bitcount);dev->bitcount++;if(dev->bitcount == 8){dev->bitcount = 0;dev->bytecount++;}}return IRQ_HANDLED;}static int setup_interrupts(void){int result;dht11_dev->irq = gpio_to_irq(dht11_dev->pin);result = request_irq(dht11_dev->irq, dht11_interrupt, IRQ_TYPE_EDGE_BOTH, DEVICE_NAME, (void *)dht11_dev);switch (result) {case -EBUSY:printk(KERN_ERR "*%s(): IRQ %d is busy\n", __func__, dht11_dev->irq);return -EBUSY;case -EINVAL:printk(KERN_ERR "*%s(): Bad irq number or handler\n", __func__);return -EINVAL;default://printk(KERN_INFO "*%s():Interrupt %04x obtained\n", __func__, dht11_dev->irq);break;}return 0;}static void clear_interrupts(void){free_irq(dht11_dev->irq, (void *)dht11_dev);    if(gpio_request(dht11_dev->pin, DEVICE_NAME)){printk(KERN_INFO "[%s] gpio_request \n", __func__);return;}s3c_gpio_cfgpin(dht11_dev->pin, S3C_GPIO_OUTPUT);s3c_gpio_setpull(dht11_dev->pin, S3C_GPIO_PULL_NONE);//s5p_gpio_set_drvstr(dht11_dev->pin, S5P_GPIO_DRVSTR_LV2);gpio_set_value(dht11_dev->pin, 1);gpio_free(dht11_dev->pin);}static int dht11_reset(struct dht11_sensor_dev *dev){    if(gpio_request(dht11_dev->pin, DEVICE_NAME)){printk(KERN_INFO "[%s] gpio_request \n", __func__);return -1;}//s3c_gpio_cfgpin(dht11_dev->pin, S3C_GPIO_OUTPUT);s3c_gpio_cfgpin(dht11_dev->pin, S3C_GPIO_OUTPUT);s3c_gpio_setpull(dht11_dev->pin, S3C_GPIO_PULL_NONE);//s5p_gpio_set_drvstr(dht11_dev->pin, S5P_GPIO_DRVSTR_LV2);gpio_set_value(dht11_dev->pin, 1);dev->write_bit(dev->pin, 0);msleep(18);dev->write_bit(dev->pin, 1);s3c_gpio_cfgpin(dev->pin, S3C_GPIO_INPUT);dev->delay(20);gpio_free(dht11_dev->pin);return 0;}static int dht11_checksum(struct dht11_sensor_dev *dev){char tmp = 0;tmp = dev->value[0] + dev->value[1] + dev->value[2] + dev->value[3];if(tmp != dev->value[4]){//printk(KERN_INFO "[%s] %d %d\n", __func__, dev->value[4], tmp);return 0;}return 1;}static int dht11_sensor_open(struct inode *inode, struct file *filp){if(dht11_dev->lock)return -EBUSY;try_module_get(THIS_MODULE);dht11_dev->lock = 1;return 0;}static int dht11_sensor_release(struct inode *inode,struct file *filp){module_put(THIS_MODULE);dht11_dev->lock = 0;return 0;}static ssize_t dht11_sensor_read(struct file *filp,char __user *buf,size_t size,loff_t *f_pos){unsigned long length =(size>48)? 48:size;int result = 0;char msg[48];dht11_dev->started = 0;dht11_dev->bitcount = 0;dht11_dev->bytecount = 0;dht11_dev->value[0] = 0;dht11_dev->value[1] = 0;dht11_dev->value[2] = 0;dht11_dev->value[3] = 0;dht11_dev->value[4] = 0;if(!dht11_reset(dht11_dev)){do_gettimeofday(&dht11_dev->lasttv);setup_interrupts();}else{dprint("*%s(): reset fail \n", __func__);return -1;}msleep(20);clear_interrupts();//for(i = 0; i < 48; i++) dht11_dev->msg[i] = -1;sprintf(msg, "Humidity=%d.%d%%\nTemperature=%d.%dC\nResult=%d\n%c",\dht11_dev->value[0], dht11_dev->value[1], \dht11_dev->value[2], dht11_dev->value[3], \dht11_checksum(dht11_dev), '\0');length = strlen(msg);dprint(KERN_INFO "*%s(): length %lu\n", __func__, length);#if 0while (length && *ptr) {put_user(*(ptr++), buf++);length--;result++;}put_user('\0', buf++);result++;*f_pos += result;return result;#elseresult=copy_to_user(buf, msg + *f_pos, length);//*f_pos += length;*f_pos = 0;//if(result) return length - result;//else result = length;return length;#endif}#if 0static ssize_t dht11_sensor_write(struct file *filp,const char __user *buf,size_t size,loff_t *f_pos){return 0;}#endifstatic struct file_operations dht11_sensor_fops={.owner = THIS_MODULE,.read = dht11_sensor_read,.open = dht11_sensor_open,.release = dht11_sensor_release,};static void dht11_sensor_setup_cdev(struct dht11_sensor_dev *dev,int minor,struct file_operations *fops){int err, devno = MKDEV(major, minor);cdev_init(&(dev->cdev), fops);dev->cdev.owner = THIS_MODULE;dev->cdev.ops = fops;err=cdev_add(&(dev->cdev), devno, 1);if(err){printk(KERN_NOTICE"erro %d adding %s %d\n",err,DEVICE_NAME,minor);}}int __init dht11_sensor_init(void){int result;dev_t devno=MKDEV(major,0);if(major){result = register_chrdev_region(devno, 1, DEVICE_NAME);}else{result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);}if(result < 0){printk(KERN_WARNING"%s: unable to get major %d\n",DEVICE_NAME,major);return result;}dht11_dev=kmalloc(sizeof(struct dht11_sensor_dev),GFP_KERNEL);if(!dht11_dev){result=-ENOMEM;goto fail_malloc;}dht11_class = class_create(THIS_MODULE, DEVICE_NAME);device_create(dht11_class, NULL, MKDEV(DEVICE_MAJOR, 0), NULL, DEVICE_NAME);dht11_sensor_setup_cdev(dht11_dev, 0, &dht11_sensor_fops);dht11_dev->pin = GPIO_DOUT;dht11_dev->delay = usdelay;dht11_dev->write_bit = gpio_write_bit;        result = gpio_request(dht11_dev->pin, DEVICE_NAME);if(result){printk(KERN_INFO "[%s] gpio_request \n", __func__);goto fail_gpio;}//s3c_gpio_cfgpin(dht11_dev->pin, S3C_GPIO_OUTPUT);s3c_gpio_cfgpin(dht11_dev->pin, S3C_GPIO_OUTPUT);s3c_gpio_setpull(dht11_dev->pin, S3C_GPIO_PULL_NONE);//s5p_gpio_set_drvstr(dht11_dev->pin, S5P_GPIO_DRVSTR_LV2);gpio_set_value(dht11_dev->pin, 1);//gpio_direction_output(dht11_dev->pin, 1);gpio_free(dht11_dev->pin);return 0;fail_gpio:kfree(dht11_dev);fail_malloc:unregister_chrdev_region(MKDEV(major,0),1);return result;}void  __exit dht11_sensor_exit(void){cdev_del(&dht11_dev->cdev);device_destroy(dht11_class, MKDEV(major, 0));class_destroy(dht11_class);//gpio_free(dht11_dev->pin);kfree(dht11_dev);unregister_chrdev_region(MKDEV(major, 0), 1);//printk("%s device uninstalled OK!\n", DEVICE_NAME);}module_init(dht11_sensor_init);module_exit(dht11_sensor_exit);MODULE_AUTHOR("jvaemape");MODULE_DESCRIPTION("S3C GPIO MQ2 Drive");MODULE_LICENSE("Dual BSD/GPL");


更多相关文章

  1. Android架构分析之Android驱动程序开发
  2. android 电容屏(二):驱动调试之基本概念篇
  3. android 电容屏(二):驱动调试之基本概念篇
  4. android模块&相关技术
  5. android 电容屏(二):驱动调试之基本概念篇
  6. Android——体系架构 +四层
  7. Android(安卓)体系结构介绍
  8. android 电容屏(二):驱动调试之基本概念篇
  9. Android(安卓)驱动开发文章收录

随机推荐

  1. H5中利用canvas绘制video
  2. Android(安卓)SDK tools adb.exe下文件丢
  3. Android中ps命令各字段的含义
  4. TextView内容太长怎么办?
  5. android 开发中遇到的问题及解决方法
  6. android学习笔记---59_各种图形的使用介
  7. Android Map API key 申请
  8. Android新特性v7 - CardView
  9. androidのadb input使用
  10. android app界面背景替换