驱动开发11-1编写IIC驱动-读取温湿度数据
- IT业界
- 2025-08-14 18:45:01

头文件 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 <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #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 <linux/init.h> #include <linux/module.h> #include <linux/i2c.h> #include <linux/fs.h> #include <linux/device.h> #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[]={ { patible="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-1编写IIC驱动-读取温湿度数据由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“驱动开发11-1编写IIC驱动-读取温湿度数据”