Linux在应用层上使用I2C

Linux在应用层上使用I2C

通常情况下i2c读写一般是在kernel中使用,但是在应用层上一样可以使用。在应用上可以通过读写/dev/i2c-x这个节点从而控制i2c接口进行读写数据。
通常一个SOC有多个I2C控制器,假设有这个SOC有3个控制器,我们会在/dev目录下看到i2c-0、i2c-1、i2c-2,计数从0开始。

在应用层使用I2C步骤

1.首先使用的时候需要包含两个头文件。
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
这个两个头文件作用是使用ioctrl的时候应用和驱动的结构体数据类型保持一致。这个两个头文件也是从内核中拷贝过来的。
文件在内核的目录是。
include/linux/i2c-dev.h
2、使用open函数打开/dev/i2c-x节点。
假设我们需要读写的是i2c0这个节点,在使用i2c控制器进行读写的时候,首先我们需要先open /dev/i2c-0这个节点,然后获得一个句柄,使用这个句柄去调用读写函数。

int fd = open(/dev/i2c-0, O_RDWR);	//open /dev/i2c-0这个节点,获得句柄fd。

3、I2C写函数实现。
前面我们已经获得了句柄fd,和我们在kernel中使用I2C一样,我们需要知道写的I2C设备的设备地址(slave address),还有你需要写的I2C的寄存器地址(register address)。有了这个三样东西我们就可以往I2C设备中进行写素具了。

struct i2c_rdwr_ioctl_data work_queue;  //分配一个struct i2c_rdwr_ioctl_data结构体变量,这个是用来存储我们要发送的数据的。work_queue.nmsgs = 1;		  //因为是I2C的读函数,所以我们需要一个msg就够了,如果是读函数需要两个msg,这里的nmsgs设置为2
work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));   //msgs是一个指针,所以需要分配msg内存,用来保存msg的数据buf[0] = register_address;   //保存寄存器地址work_queue.msgs[0].len = 1 + size;  //1 + size 1表示的是register的长度,占一个字节,size表示的是我们要写的数据长度
work_queue.msgs[0].flags = 0; // I2C的读写标志位 0:write 1:read  (如果不清楚需要回去看I2C的基础知识)
work_queue.msgs[0].addr = slave_addr;   //要写的I2C设备地址
work_queue.msgs[0].buf[0] = buf;        //要发送的数据存储的地址ioctl(fd, I2C_RDWR, (unsigned long)&work_queue);   //最后一步需要使用ioctl将数据发送出去。这里最后是调用到kernel的底层驱动,然后将数据通过I2C的控制器将数据传输出去。

4、I2C读函数实现。
I2C的读函数和写函数实现的方式类似,但是有两点不同
1、flags这个标志位在读的时候需要修改为1.
2、work_queue.nmsgs未2,因为根据I2C的标准协议,在发起读之前,需要先写寄存器地址,才能发起读操作。所以第一个msg是为了写寄存器地址,第二msg才是用来读的。

struct i2c_rdwr_ioctl_data work_queue; //分配一个struct i2c_rdwr_ioctl_data结构体变量,这个是用来存储我们要发送的数据的和读的数据。work_queue.nmsgs = 2;
work_queue.msgs  = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));   //分配两个msg。//第一个msg的配置
work_queue.msgs[0].len = 1;
work_queue.msgs[0].flags = 0; // 0:write 1:read  
work_queue.msgs[0].addr = slave_addr;
work_queue.msgs[0].buf = &reg; //reg addrwork_queue.msgs[1].len = size;	//要读的长度
work_queue.msgs[1].flags = 1; // 0:write 1:read  表示为读flag
work_queue.msgs[1].addr = slave_addr;  //设备地址
work_queue.msgs[1].buf = buf;   //buf:读取的数据保存的地址ioctl(fd, I2C_RDWR, (unsigned long)&work_queue); //最后一步需要使用ioctl将数据发送出去和读回来。这里最后是调用到kernel的底层驱动,然后将数据通过I2C的控制器将数据传输出去和读回来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

led手电筒照明线性恒流驱动芯片推荐:SM2123EGL双通道可调光

LED手电筒照明线性恒流驱动芯片是一种专门用于LED手电筒的照明系统的关键组件。它采用了线性恒流驱动技术&#xff0c;可以确保LED手电筒在不同电池电压和温度变化下&#xff0c;保持恒定的亮度输出&#xff0c;提高了LED手电筒的稳定性和可靠性。 LED手电筒照明线性恒流驱动芯…

VScode右键没有go to definition选项

1. 背景 1.1. 项目代码在远程服务器上&#xff1b; 1.2. win重装系统&#xff0c;重新安装vscode出现问题&#xff0c;没重装系统之前是没问题的&#xff1b; 2. 问题 打开vscode&#xff0c;通过ssh链接远程服务器中的项目代码后&#xff0c;选中函数右键没有go to defini…

大连理工大学软件学院2022年秋季学期《矩阵与数值分析》上机作业

文章目录 《计算机科学计算》第二版162页第12题&#xff08;1&#xff09;162页第16题216页第12题 《数值分析方法与应用》一、基础知识部分1、5、 二、线性方程组求解2、6、 三、非线性方程组求解1、4、 四、插值与逼近1、5、7、 五、数值积分2、 六、微分方程数值解法1、 《计…

机房自动化监控手把手分享给你 - 番外1:声光报警实现

本文章是一个机房自动化监控实际项目系列文章的番外篇&#xff0c;有个朋友问能否补充一个声光报警的实现&#xff0c;我仔细一想&#xff1a;虽然我不在这个项目中实现声光报警&#xff0c;但我在其他项目用过&#xff0c;使用的设备器件成本很低。那就以这个项目为背景&#…

视频转为序列图的软件,让视频批量转为序列图

你是否曾经遇到过这样的困境&#xff1a;需要将一段视频转为一系列的图片&#xff0c;但却没有合适的工具来完成&#xff1f;或许你曾经手动截图&#xff0c;或者用其他方式&#xff0c;但结果往往不尽如人意&#xff0c;图片质量差、色彩失真、画面不清晰。现在&#xff0c;让…

C语言动态内存管理

我们目前知道的开辟内存空间的方法有&#xff1a; 1.创建变量 2.创建数组&#xff1b; 但是这2种方法开辟的空间大小都是固定的&#xff0c;如果是数组的话确认了大小之后是无法改变的&#xff1b; int a10;//在栈区空间上开辟4个字节的空间&#xff1b;int arr[10];//在栈…

C++ 模板进阶

目录 一、非类型模板参数 二、模板的特化 1、函数模板特化 2、类模板特化 全特化 偏特化 3、例题 三、模板分离编译 1、定义 2、解决方法 3、模板总结 一、非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xf…

vue 实现调起打印机打印图片 与图片下载

需要创建一个标签&#xff0c;可以放在页面用样式隐藏起来 <div id"printable-content" style"display: none"><div><el-imagestyle"width: 60px; height: 60px; border-radius: 50%"v-if"barrcodePicture":src"b…

10本审稿及出版效率均较好的科普期刊参数分享!

医、药、护、技及医学工程等相关的人员&#xff0c;进行卫生高级职称评审时&#xff0c;需要在专业期刊上公开发表本专业学术论文&#xff0c;论文的方向、内容质量以及发表的刊物都至关重要。今天常笑医学给大家整理了10本审稿及出版效率均较好的科普期刊&#xff01;参数分享…

【开源GPT项目 - 在问】让知识无界,智能触手可及

Chatanywhere: chatAnywhere 在问 | 让知识无界&#xff0c;智能触手可及 项目简介 这是一个免费的在线聊天工具&#xff0c;旨在让用户更方便地享受科技带来的便利。用户可以使用我们的工具来获取答案、寻求建议、进行翻译和计算等等。这是由一位个人开发者创建的&#xff…

MLP(多层感知机) 虚战1

使用Keras实现MLP 前两节地址&#xff1a; CSDNmatplotlib 虚战1-CSDN博客 &#xff08;数据的获取在这有说明&#xff09; 数据预处理 虚战1-CSDN博客CSDN 数据预处理的最后一步&#xff1a;将数据集分为 训练数据集、测试数据集和校验数据集。 训练数据集&#xff1a…

leetcode10-困于环中的机器人

题目链接&#xff1a; https://leetcode.cn/problems/robot-bounded-in-circle/description/?envTypestudy-plan-v2&envIdprogramming-skills 思路&#xff1a; 首先&#xff0c;题目要寻找的是成环的情况。 1.如果经历一次指令后的方向仍为北方&#xff0c;要使得机器人循…

vue中key的用法

加key是提升vue渲染效率&#xff0c;减少DOM操作。 vue列表元素的更新机制&#xff1a; 当列表元素没有设置key的时候&#xff0c;vue判断是否操作这个DOM元素&#xff0c;是根据新旧两次数据的元素顺序进行对比&#xff0c;看一下元素内容是否发生变化。发生变化vue就操作这个…

安卓开发--proj4j坐标转换快速上手

本节专门讲解proj4j的使用,关于坐标转换原理,等我后面有时间了再讲解下。 现在最新版本的1.3.0版本使用起来很方面,不需要你手动导包,只要配置下gradle就行了。 目录 1.gradle配置 2.Activity使用 2.1方式1:Obtaining CRSs by name【通过epsg名字获取】 2.2方式2:Obta…

优先队列的使用c++,哈夫曼树带权路径长度

在一个果园里&#xff0c;达达已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。达达决定把所有的果子合成一堆。 每一次合并&#xff0c;达达可以把两堆果子合并到一起&#xff0c;消耗的体力等于两堆果子的重量之和。可以看出&#xff0c;所有的果子…

TS 36.211 V12.0.0-通用功能

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

【Flutter 开发实战】Dart 基础篇:最基本的语法内容

在深入了解 Dart 这门编程语言之前&#xff0c;我们需要了解一些关于 Dart 的最基本的知识&#xff0c;像是常量、变量、函数等等&#xff0c;这样才能够让我们的开发效率更上一层楼。在本节&#xff0c;我们将探讨一些基础语法&#xff0c;包括入口方法 main、变量、常量以及命…

【数位dp】【动态规划】C++算法:233.数字 1 的个数

作者推荐 【动态规划】C算法312 戳气球 本文涉及的基础知识点 动态规划 数位dp LeetCode:233数字 1 的个数 给定一个整数 n&#xff0c;计算所有小于等于 n 的非负整数中数字 1 出现的个数。 示例 1&#xff1a; 输入&#xff1a;n 13 输出&#xff1a;6 示例 2&#xff…

MySQL 8.0中新增的功能(七)

EXPLAIN ANALYZE 语句 在MySQL 8.0.18中引入了一种新形式的EXPLAIN语句&#xff0c;即EXPLAIN ANALYZE&#xff0c;它提供了关于SELECT语句执行的扩展信息&#xff0c;以TREE格式显示查询过程中每个迭代器的执行计划&#xff0c;并可以比较查询的预计成本与实际成本。这些信息…

类和对象的定义以及使用

文章目录 1. 类和对象的基本概念1.1 JAVA是面向对象语言1.2 类和对象的描述 2. 类与对象的定义与使用2.1 类的定义格式2.2 类的实例化(对象的创建)2.3 举个例子 3. 对象的构造及初始化3.1构造方法3.1.1构造方法的定义3.1.2 构造方法的特性 4.2 默认初始化5.4 就地初始化 4.this…