在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例Linux内核编程 → linux内核驱动之DHT11

linux内核驱动之DHT11

Linux内核编程

下载此实例
  • 开发语言:C/C++
  • 实例大小:3.79KB
  • 下载次数:8
  • 浏览次数:497
  • 发布时间:2019-04-10
  • 实例类别:Linux内核编程
  • 发 布 人:dihongwei
  • 文件格式:.c
  • 所需积分:5
 相关标签: linux 内核 驱动

实例介绍

说明:通过内核驱动dht11实现温度湿度的检测

核心代码:

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/wait.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/uaccess.h>


/*定义DHT11接入的IO口*/
#define DHT11_PIN EXYNOS4_GPB(4)

#define DEVNAME "dht11"


/* 用于接受采集到的数据*/
unsigned char dht11_data_buf[6];
/*  判断校验的标记*/
unsigned char check_flag;

/*  read one bit */
static int dht11_read_bit(void)
{
    gpio_direction_input(DHT11_PIN);
    return gpio_get_value(DHT11_PIN);
}


/*  read byte */
static unsigned char dht11_read_byte(void)
{
    int i = 0;
    int num ;
    unsigned char flag = 0;
    unsigned char data = 0;

    for(num = 0; num < 8; num ){
        i = 0;
        /*没一个位发送起始的时候,会有50us低电平*/
        while(gpio_get_value(DHT11_PIN) == 0){
            udelay(10);
            i ;
            if(i > 5){
                break;
            }
        }

        flag = 0x00;
        /*26-28 us 高电平表示'0'*/
        udelay(30);

        if(gpio_get_value(DHT11_PIN)){
            flag = 0x01;
        }
        i = 0;
        /*如果读到的数据为'1'的话,70us 高电平,将这段时间的高电平读取完毕*/
        while(gpio_get_value(DHT11_PIN)){
            udelay(20);
            i ;
            if(i > 3)
                break;
        }
        data <<= 1;
        data |= flag;
    }
    return data;
}


/*  设备 read_data*/
static void dht11_read_data(void)
{
    int i = 0;

    /*
       主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。
       DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.
       主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,
       主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
     */
    gpio_direction_output(DHT11_PIN,0);
    mdelay(30);
    gpio_direction_output(DHT11_PIN,1);
    udelay(20);

    if(dht11_read_bit() == 0){
        while(!gpio_get_value(DHT11_PIN)){
            udelay(10);
            i ;
            if(i > 8){
                printk("dht11 read data %d error\n",__LINE__);
                break;
            }

        }
        i = 0;
        while(gpio_get_value(DHT11_PIN)){
            udelay(10);
            i ;
            if(i > 8){
                printk("dht11 read data %d error\n",__LINE__);
                break;
            }
        }
        for(i = 0; i < 5; i ){
            dht11_data_buf[i] = dht11_read_byte();
        }
        dht11_data_buf[5] = dht11_data_buf[0] dht11_data_buf[1]
                 dht11_data_buf[2] dht11_data_buf[3];
        if(dht11_data_buf[5] == dht11_data_buf[4]){
            check_flag = 0xff;        
        }else if(dht11_data_buf[4] != dht11_data_buf[5]){
            check_flag = 0x00;
        }
    }
}


/*  设备 read*/
static ssize_t dht11_read(struct file *file, char __user *buffer, ssize_t size, loff_t *offset)
{
    int ret;
//    unsigned long flags;

//    local_irq_save(flags);
    dht11_read_data();
//    local_irq_restore(flags);

    if(check_flag == 0xff){
        ret = copy_to_user(buffer,dht11_data_buf,sizeof(dht11_data_buf));
        if(ret < 0){
            printk("copy_to_user error\n");
            return -EAGAIN;
        }else{
            return 0;
        }
    }else{
        printk("check error\n");
        return -EAGAIN;
    }
}

/* 定义杂项设备操作的结构体并且初始化成员的函数指针 */
static const struct file_operations dht11_fops = {
    .read = dht11_read,
};


/* 定义杂项设备结构体*/
static struct miscdevice dht11_miscdev = {
    .minor = MISC_DYNAMIC_MINOR,   /* 自动分配次设备号 */
    .name = DEVNAME,               /* 杂项设备的名字 */
    .fops = &dht11_fops,           /* 杂项设备操作的结构体(驱动函数集合)*/
};


static int dht11_init(void)
{
    int ret;

    ret = gpio_request(DHT11_PIN,DEVNAME);

    if(ret){
        printk("gpio_retquest for dht11 is filed\n");
        return ret;
    }
    
    ret = misc_register(&dht11_miscdev);
    return ret;
}

static void dht11_exit(void)
{
    misc_deregister(&dht11_miscdev);
    gpio_free(DHT11_PIN);
}


module_init(dht11_init);
module_exit(dht11_exit);

MODULE_LICENSE("GPL");


标签: linux 内核 驱动

实例下载地址

linux内核驱动之DHT11

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警