• 华清远见上海中心22071班


    #include
    #include
    #include
    #include
    #include
    #include
    #include"si7006.h"

    int major;
    struct class *cls;
    struct device *dev;
    struct i2c_client *tclient;
    //获取温湿度数据的函数
    int i2c_read_hum_tem(unsigned char reg)
    {
        int ret;
        //读消息的封装
        char r_buf[]={reg};
        unsigned short val;//读的数据
        struct i2c_msg r_msg[]={
             [0]={
                 .addr=tclient->addr,
                .flags=0,
                .len=1,
                .buf=r_buf,   
             },
             [1]={
                .addr=tclient->addr,
                .flags=1,
                .len=2,
                .buf=(char *)&val,   
             },
        };
        //消息的传输
        ret=i2c_transfer(tclient->adapter,r_msg,ARRAY_SIZE(r_msg));
        if(ret!=ARRAY_SIZE(r_msg))
        {
            printk("i2c获取温湿度数据失败\n");
            return EAGAIN;
        }
        return val;
    }

     //匹配成功后执行probe
    int si7006_open(struct inode *inode, struct file *file)
    {
        printk("open\n");
        return 0;
    }
    ssize_t si7006_read(struct file *file, char *ubuf, size_t size, loff_t *off)
    {
         printk("read\n");
        return 0;
    }
    ssize_t si7006_write(struct file *file, const char  *ubuf, size_t size, loff_t *off)
    {
         printk("write\n");
        return 0;
    }
    long si7006_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    {
        int tem,hum;
        int ret;
        switch(cmd)
        {
            case GET_HUM:
                hum=i2c_read_hum_tem(0xe5);
                ret=copy_to_user((void *)arg,(void *)&hum,sizeof(int));
                if(ret)
                {
                    printk("copy_to_user fild\n");
                    return EINVAL;
                }
                break;
            case GET_TEM:
                tem=i2c_read_hum_tem(0xe3);
                ret=copy_to_user((void *)arg,(void *)&tem,sizeof(int));
                if(ret)
                {
                    printk("copy_to_user fild\n");
                    return EINVAL;
                }
                break;
        }
        return 0;
    }
    int si7006_close(struct inode *inode, struct file *file)
    {
         printk("close\n");
        return 0;
    }
    struct file_operations fops={
        .open=si7006_open,
        .read=si7006_read,
        .write=si7006_write,
        .unlocked_ioctl=si7006_ioctl,
        .release=si7006_close,
    };

    int si7006_probe(struct i2c_client *client, const struct i2c_device_id *id)
    {
        //把总线驱动指针变成全局的
        tclient=client;
        //注册字符设备驱动
        major=register_chrdev(0,"si7006",&fops);
        if(major<0)
        {
            printk("字符设备驱动注册失败\n");
            return major;
        }
        printk("字符设备驱动注册成功\n");
        //自动创建设备节点
        cls=class_create(THIS_MODULE,"si7006");
        if(IS_ERR(cls))
        {
            printk("向上提交目录失败\n");
            return PTR_ERR(cls);
        }
        printk("向上提交目录成功\n");
        dev=device_create(cls,NULL,MKDEV(major,0),NULL,"si7006");
         if(IS_ERR(dev))
        {
            printk("向上提交设备信息失败\n");
            return PTR_ERR(dev);
        }
        printk("向上提交设备信息成功\n");
        return 0;
    }
       //设备分离后执行remove
    int si7006_remove(struct i2c_client *client)
    {
        printk("%s:%d\n",__func__,__LINE__);
        return 0;
    }
    //定义设备树匹配表
    struct of_device_id oftable[]=
    {
      {.compatible="hqyj,si7006",},
      {}  
    };
    MODULE_DEVICE_TABLE(of,oftable);
    //定义对象并且初始化
    struct i2c_driver si7006={
        .probe=si7006_probe,
        .remove=si7006_remove,
        .driver={
            .name="tem_hum_driver",
            .of_match_table=oftable,
        },
    };

    module_i2c_driver(si7006);
    MODULE_LICENSE("GPL");

     #include
    #include
     #include
     #include
     #include
     #include
     #include
      #include
    #include"si7006.h"
    int main(int argc, char const *argv[])
    {
        int hum,tem;
        float hum1,tem1;
        int ret;
        int fd=open("/dev/si7006",O_RDWR);
        if(fd<0)
        {
            printf("打开设备文件失败\n");
            exit(-1);
        }
        while(1)
        {
            ioctl(fd,GET_TEM,&tem);
            ioctl(fd,GET_HUM,&hum);
            //字节序的转换
            hum=ntohs(hum);
            tem=ntohs(tem);
            //温湿度数据计算
            hum1=125.0*hum/65536-6;
            tem1=175.72*tem/65536-46.85;
            printf("tem:%f  hum:%f\n",tem1,hum1);
            sleep(1);
        }
        return 0;
    }

     #ifndef __SI7006_H__
    #define __SI7006_H__
    #define GET_TEM  _IOR('m',0,int)
    #define GET_HUM  _IOR('m',1,int)
    #endif

  • 相关阅读:
    Type-C口充电器头为什么没有电压输出?
    Java常见跳出循环的4种方式总结、switch中的break与return、lamada表达式中foreach如何正确选择退出方式
    RocketMQ单机环境搭建
    《golang设计模式》第二部分·结构型模式-04-装饰器模式(Decorator)
    内网渗透-linux权限维持
    node笔记记录36process之1
    layui框架实战案例(21):layui table单元格显示图片导致复选框冗余的解决方案
    sqllabs第46关 order by 注入(通过盲注)
    C语言访问Mysql
    Qt中QThread安全退出方式总结
  • 原文地址:https://blog.csdn.net/qq_60135456/article/details/128121639