Qualcomm技术论坛
直播中

高川

8年用户 248经验值
私信 关注
[经验]

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

  燃气烟雾检测模块MQ-2在上篇博客中已经写好了,接下来是温湿度检测模块dht11了,模块信息在前面已经介绍过了,这里就不再赘述了,直接看程序:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include time.h>

#include

#include



#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 %dn", __func__, dev->value[4], tmp);

        return -1;

    }

    return 1;

}



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

{

    printk("dht11_sensor_openn");     

    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_readn");

    dht11_start();

    dht11_read();

    msleep(10);

    result=dht11_checksum(dht11_dev);

    if(result<0)

            return -EAGAIN;  



    printk("---Humidity=%d.%d%%RHn---Temperature=%d.%dCn",

            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 errn");

         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 %sn",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

#include

#include

#include

#include

#include

#include


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 failedn");

        return fd;

    }

   

    ret = read(fd, buf, 4);

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

        printf("errno= %dn", errno);

        printf("Mesg----%sn",strerror(errno));       

        perror("read failed");

        return ret;

    }

    printf("---Humidity=%d.%d%%RHn---Temperature=%d.%dCn", buf[0], buf[1], buf[2], buf[3]);

    close(fd);


    return 0;

}

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

更多回帖

发帖
×
20
完善资料,
赚取积分