发 帖  
原厂入驻New
申请华秋企业认证 多层板首单免费打样!
30s提交资料,10分钟通过审核(免费赔付+顺丰包邮)>>立即报名

[经验] 基于Dragonboard 410c的燃气烟雾检测器(三)

2018-9-28 11:47:50  23030 Qualcomm DragonBoard 检测器
分享
0
  燃气烟雾检测模块MQ-2在上篇博客中已经写好了,接下来是温湿度检测模块dht11了,模块信息在前面已经介绍过了,这里就不再赘述了,直接看程序:

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/workqueue.h>

#include <linux/slab.h>

#include <linux/input.h>

#include <linux/init.h>

#include <linux/errno.h>

#include <linux/serio.h>

#include <linux/delay.h>

#include <linux/platform_device.h>

#include <linux/clk.h>

#include <linux/wait.h>

#include <linux/sched.h>

#include <linux/cdev.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

#include <linux/of_gpio.h>

#include <linux/delay.h>

#include <linux/printk.h>

#include <linux/time.h>

#include <linux/irq.h>

#include <asm-generic/uaccess.h>



#define DEVICE_NAME "dht11"

#define DEVICE_MAJOR 0



struct dht11_sensor_dev{

    int pin;

    unsigned char value[5];

    int signal;

    int time;

    int count;

    dev_t devno;

    struct class *dht11_class;

    struct cdev cdev;

    struct mutex read_data;

    struct timeval lasttv;

    struct timeval tv;

    struct work_struct dht11_work;

};



static struct dht11_sensor_dev *dht11_dev;



static int read_byte(void){

        unsigned char data;

        int i = 0;

    for(i = 0; i < 8; i++){

        while(!gpio_get_value(dht11_dev->pin));

        udelay(30);

        data <<= 1;

        IF(gpio_get_value(dht11_dev->pin) == 1){

            data |=0x01;

            while(gpio_get_value(dht11_dev->pin));

        }else{

            data |=0x00;

        }         

    }

    return data;

}



static void dht11_read(void){



    int i = 0;



    dht11_dev->signal = gpio_get_value(dht11_dev->pin);

    if(dht11_dev->signal == 0){

        while(!gpio_get_value(dht11_dev->pin));

        while(gpio_get_value(dht11_dev->pin));

        for(i = 0; i < 5; i++){

            dht11_dev->value = read_byte();

        }

    }

}



static int dht11_start(void)

{

    gpio_direction_output(dht11_dev->pin, 0);     

    msleep(20);

    gpio_set_value(dht11_dev->pin,1);

    udelay(20);

    gpio_direction_input(dht11_dev->pin);

    do_gettimeofday(&dht11_dev->lasttv);

    dht11_dev->count=0;

    return 0;

}





static int dht11_checksum(struct dht11_sensor_dev *dev)

{

    int tmp = 0;

    tmp = dev->value[0] + dev->value[1] + dev->value[2] + dev->value[3];

     



    if((tmp != dev->value[4]) || (dev->value[4] == 0) || (tmp == 0) ){

        printk(KERN_INFO "[%s] %d %d\n", __func__, dev->value[4], tmp);

        return -1;

    }

    return 1;

}



static int dht11_sensor_open(struct inode *inode, struct file *filp)

{

    printk("dht11_sensor_open\n");     

    return 0;

}



static ssize_t dht11_sensor_read(struct file *filp,char __user *buf,size_t  

size,loff_t *f_pos)

{

    int result = 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;

  

    printk("dht11_sensor_read\n");

    dht11_start();

    dht11_read();

    msleep(10);

    result=dht11_checksum(dht11_dev);

    if(result<0)

            return -EAGAIN;  



    printk("---Humidity=%d.%d%%RH\n---Temperature=%d.%dC\n",\

            dht11_dev->value[0], dht11_dev->value[1], \

            dht11_dev->value[2], dht11_dev->value[3]);

    result=copy_to_user(buf,&dht11_dev->value,4);

    if(result<0)

    {

         printk("copy to user err\n");

         return -EAGAIN;

    }  

    return  result;            

}



static int dht11_sensor_release(struct inode *inode,struct file *filp)

{

    module_put(THIS_MODULE);

    return 0;

}



static struct file_operations dht11_sensor_fops={

    .owner   = THIS_MODULE,

    .open    = dht11_sensor_open,

    .read    = dht11_sensor_read,

    .release = dht11_sensor_release,

};



//static int dht11_gpio_init(void)

static int parse_dt (struct platform_device *pdev,struct dht11_sensor_dev *data){


    int result;

    struct device_node *node = pdev->dev.of_node;

    data->pin = of_get_named_gpio(node,"thunder,gpio_data",0);

    if(gpio_is_valid(data->pin)){

    result=gpio_request(data->pin, "dht11_gpio");

    if(result)

    {

        printk(KERN_INFO "[%s] gpio_request \n", __func__);

        return -1;

    }

    gpio_direction_output(data->pin,1);

    }

    return 0;

}





static int dht11_sensor_setup_cdev(void)

{

    int ret;

    cdev_init(&(dht11_dev->cdev), &dht11_sensor_fops);

    dht11_dev->cdev.owner = THIS_MODULE;

    ret=cdev_add(&(dht11_dev->cdev),dht11_dev->devno, 1);

    if(ret)

    {

        printk(KERN_NOTICE"erro %d adding %s\n",ret,DEVICE_NAME);

    }

    return ret;

}



static int dht11_probe(struct platform_device *pdev){

    int result;

    dht11_dev=kmalloc(sizeof(struct dht11_sensor_dev),GFP_KERNEL);

    if(!dht11_dev)

    {

        result=-ENOMEM;

        goto allocate_memory_fail;

    }

    if(DEVICE_MAJOR)

    {

        result = register_chrdev_region(dht11_dev->devno, 1, DEVICE_NAME);

    }

    else

    {

        result = alloc_chrdev_region(&dht11_dev->devno, 0, 1, DEVICE_NAME);

    }

    if(result < 0)

    {

        printk("register_chrdev_region err!\n");

        goto chardev_region_fail;

    }

    dht11_dev->dht11_class = class_create(THIS_MODULE, DEVICE_NAME);

    if(IS_ERR(dht11_dev->dht11_class))

    {

             printk("Err: faiLED in creating class.\n");

             goto class_create_fail;

    }  

    device_create(dht11_dev->dht11_class, NULL,dht11_dev->devno, NULL,  

DEVICE_NAME);

    result = parse_dt(pdev,dht11_dev);

    if(result<0)

        goto gpio_request_fail;

    result=dht11_sensor_setup_cdev();

    if(result<0)

        goto cdev_fail;

    mutex_init(&dht11_dev->read_data);

    printk("dht11 init ok!\n");

    return 0;

     

gpio_request_fail:

    cdev_del(&dht11_dev->cdev);

cdev_fail:

    device_destroy(dht11_dev->dht11_class,dht11_dev->devno);

    class_destroy(dht11_dev->dht11_class);

class_create_fail:

    unregister_chrdev_region(dht11_dev->devno,1);

chardev_region_fail:

allocate_memory_fail:

    kfree(dht11_dev);

    return result;

}



static int dht11_remove(struct platform_device *pdev)

{

    cdev_del(&dht11_dev->cdev);

    device_destroy(dht11_dev->dht11_class,dht11_dev->devno);

    class_destroy(dht11_dev->dht11_class);     

    unregister_chrdev_region(dht11_dev->devno, 1);

    kfree(dht11_dev);



    return 0;

}



static struct of_device_id dht11_match_table[] = {

    { .compatible = "thunder,dht11",},

    { },

};



static struct platform_driver dht11_driver = {



    .probe = dht11_probe,

    .remove = dht11_remove,

    .driver = {

        .owner = THIS_MODULE,

        .name = DEVICE_NAME,

        .of_match_table = dht11_match_table,

    },

};



module_platform_driver(dht11_driver);



MODULE_AUTHOR("wi");

MODULE_DESCRIPTION("DHT11 Driver");

MODULE_LICENSE("GPL");




这个模块用的是单总线,所以时序要特别注意一下,设备节点:/dev/dht11

为了检测数据的正确性,以及节点是否可用,写了下面一个小程序进行测试

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>


int main(){


    int fd;

    int ret;

    int i = 0;

    unsigned char buf[4];


    fd = open("/dev/dht11", O_RDONLY);

    if(fd < 0){

        printf("open the dht11 id failed\n");

        return fd;

    }

   

    ret = read(fd, buf, 4);

    if(ret < 0){                 //下面三个输出可以了解一下,对于打开,读写节点失败的调试很有帮助的。

        printf("errno= %d\n", errno);

        printf("Mesg----%s\n",strerror(errno));       

        perror("read failed");

        return ret;

    }

    printf("---Humidity=%d.%d%%RH\n---Temperature=%d.%dC\n", buf[0], buf[1], buf[2], buf[3]);

    close(fd);


    return 0;

}

经过测试是没有问题的。到此温湿度检测模块dht11的底层驱动也完成了。

只有小组成员才能发言,加入小组>>

45个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表