驱动开发11 编写iic驱动-读取温湿度数据

头文件 head.h

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

应用程序 si7006.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "head.h"

int main(int argc, char const *argv[])
{
    char buf[128]={0};
    unsigned short hum,tem;
    float hum1,tem1;
    int fd = open("/dev/si7006",O_RDWR);
    if(fd < 0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while(1)
    {
        //读取温湿度数据
        ioctl(fd,GET_HUM,&hum);
        ioctl(fd,GET_TEM,&tem);
        //进行字节序转换
        hum = ntohs(hum);
        tem = ntohs(tem);
        //数据转换
        hum1 = (float)hum*125/65536-6;
        tem1 = (float)tem*175.72/65536-46.85;
        printf("hum = %f    tem = %f\n",hum1,tem1);
        sleep(1);
    }
    close(fd);
    return 0;
}

驱动程序 iic.c

#include 
#include 
#include 
#include 
#include 
#include "head.h"

struct i2c_client *client1;
unsigned int major;
struct class *cls;
struct device *dev;
//封装读取温湿度数据的函数
short read_hum_tem_value(char reg)
{
    short value; //保存读到的温湿度数据
    char r_buf[] = {reg};
    //消息结构体的封装
    struct i2c_msg r_msg[] = {
        [0] = {
            .addr = client1->addr,
            .flags = 0,
            .len = sizeof(r_buf),
            .buf = r_buf,
        },
        [1] = {
            .addr =client1->addr,
            .flags = 1,
            .len = 2,
            .buf = (char *)&value,
        },
    };
    //发送消息
    int ret = i2c_transfer(client1->adapter,r_msg,2);
    if(ret != 2)
    {
        printk("消息传输失败\n");
        return -1;
    }
    return value;
}
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    short hum,tem;
    int ret;
    switch ((cmd))
    {
    case GET_HUM:
        hum = read_hum_tem_value(0xE5);
        ret = copy_to_user((void *)arg,&hum,2);
        if(ret)
        {
            printk("coyp_to_user err %d\n",__LINE__);
        }
        break;
    case GET_TEM:
        tem = read_hum_tem_value(0xE5);
        ret = copy_to_user((void *)arg,&tem,2);
        if(ret)
        {
            printk("coyp_to_user err %d\n",__LINE__);
        }
        break;
    }
    return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
//定义操作方法结构体变量并复制
struct file_operations fops = {
    .open = mycdev_open,
    .unlocked_ioctl = mycdev_ioctl,
    .release = mycdev_close,
};
//给对象分配空间并且初始化
int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    client1 = client;
    int ret;
    //float hum1,tem1;
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    //字符设备驱动的注册
    major = register_chrdev(0,"si7006",&fops);
    if(major < 0)
    {
        printk("字符设备驱动注册失败\n");
        ret = major;
        goto out1;
    }
    printk("字符设备驱动注册成功\n");
    //向上提交目录
    cls = class_create(THIS_MODULE,"si7006");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        ret = -PTR_ERR(cls);
        goto out2;
    }
    printk("向上提交目录成功\n");
    //向上提交设备节点信息
    dev = device_create(cls,NULL,MKDEV(major,0),NULL,"si7006");
    if(IS_ERR(dev))
    {
        printk("向上提交设备节点失败\n");
        ret = -PTR_ERR(dev);
        goto out3;
    }
    printk("向上提交设备节点成功\n");
    return 0;
out3:
    class_destroy(cls);
out2:
    unregister_chrdev(major,"si7006");
out1:
    return ret;
}
int i2c_remove(struct i2c_client *client)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    //设备信息的注销
    device_destroy(cls,MKDEV(major,0));
    //设备节点的销毁
    class_destroy(cls);
    //驱动的注销
    unregister_chrdev(major,"si7006");
    return 0;
}
//定义设备树匹配的表
struct of_device_id oftable[]={
    {.compatible="hqyj,si7006",},
    {},
};
struct i2c_driver i2c_drv={
    .probe=i2c_probe,
    .remove=i2c_remove,
    .driver={
        .name="si7006",
        .of_match_table=oftable,
    },
};
module_i2c_driver(i2c_drv);
MODULE_LICENSE("GPL");

效果演示

驱动开发11 编写iic驱动-读取温湿度数据_第1张图片

驱动开发11 编写iic驱动-读取温湿度数据_第2张图片

你可能感兴趣的:(驱动开发,驱动开发)