当前位置: 首页 > news >正文

linux_驱动_iic总线获取si7006温湿度

应用层si7006.c

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include "head.h"int main(int argc,char const *argv[])
{int tem,hum;float tem1,hum1;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 = 125.0*hum/65536-6;tem1 = 175.72*tem/65536-46.85;printf("tem=%f,hum=%f\n",tem1,hum1);sleep(1);}return 0;
}

驱动层myiic.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/device.h>
#include "head.h"unsigned int major;
struct class *cls;
struct device *dev;
struct i2c_client *client1;// 读取温湿度的函数
int i2c_read_hum_tem(char reg)
{short value;char r_buf[] = {reg};int ret;// 封装消息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,},};// 将消息传送ret = i2c_transfer(client1->adapter, r_msg, 2);if (ret != 2){printk("消息传输失败\n");return -EIO;}return value; // 将读取到的温度和湿度返回
}int si7006_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}long si7006_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{int tem, hum, ret;switch (cmd){case GET_HUM: // 读取湿度// 读取湿度的逻辑hum = i2c_read_hum_tem(0XE5);ret = copy_to_user((void *)arg, &hum, 4);if (ret < 0){printk("向用户拷贝数据失败\n");return ret;}break;case GET_TEM: // 读取温度// 读取温度的逻辑tem = i2c_read_hum_tem(0XE3);ret = copy_to_user((void *)arg, &tem, 4);if (ret < 0){printk("向用户拷贝数据失败\n");return ret;}break;}return 0;
}int si7006_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}struct file_operations fops = {.open = si7006_open,.unlocked_ioctl = si7006_ioctl,.release = si7006_close,
};// 给对象分配空间并初始化
int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{client1 = 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 i2c_remove(struct i2c_client *client)
{// 销毁节点device_destroy(cls, MKDEV(major, 0));// 目录和设备信息的销毁class_destroy(cls);// 驱动的注销unregister_chrdev(major, "si7006");return 0;
}// 构建设备树匹配信息
struct of_device_id oftable[] = {{.compatible = "vivi,si7006",},{},
};// 分配iic驱动对象并初始化
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");

在根节点外添加设备树

*********添加************
在stm32mp157a-fsmp1a.dts文件的根节点外部,添加如下内容:&i2c1 {pinctrl-names = "default", "sleep";//关于pinctrl的一个列表,"default"表示默认工作模式//"sleep"表示低功耗模式pinctrl-0 = <&i2c1_pins_b>;//-0表示pinctrl-name列表中第一个值defaultpinctrl-1 = <&i2c1_sleep_pins_b>;//在stm32mp15-pinctrl.dtsi文件中存在内核添加的各种用于管脚复用的节点,i2c1_pins_a就是其中之一i2c-scl-rising-time-ns = <100>;i2c-scl-falling-time-ns = <7>;status = "okay";/delete-property/dmas;  //删除不必要的属性/delete-property/dma-names;si7006@40{  //添加SI7006的从机节点compatible="hqyj,si7006";reg=<0X40>;};};

效果演示

 

 

 

 

http://www.lryc.cn/news/108084.html

相关文章:

  • 虚拟机网络图标不见了
  • CTF:信息泄露.(CTFHub靶场环境)
  • Redis学习总结
  • 云原生全栈体系(二)
  • C++设计模式之建造者设计模式
  • HDFS Erasure coding-纠删码介绍和原理
  • STM32 DHT11
  • 词法分析器
  • 【Spring】Spring之启动过程源码解析
  • 状态模式(State)
  • 【uniapp】样式合集
  • 【Spring框架】SpringBoot统一功能处理
  • 51单片机学习--按键控制流水灯模式定时器时钟
  • Django教程_编程入门自学教程_菜鸟教程-免费教程分享
  • VGG卷积神经网络-笔记
  • Python爬虫如何实现IP代理池搭建
  • 单例模式:保证一个类只有一个实例
  • 【新版系统架构补充】-七层模型
  • 第2章 C语言概述
  • vscode vue3开发常用插件(附Prettier格式化配置)
  • 【微信小程序】van-uploader实现文件上传
  • 人工智能在计算机视觉中的应用与挑战
  • 以太网接口指示灯状态分析和电路设计
  • Redis的基础
  • LeetCode 626. 换座位
  • 华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(六)
  • hash 模式和 history 模式的实现原理
  • 并发编程Part 2
  • springboot异步多线程的实现
  • 测试相关基础概念与常见开发模型