i2c_tool的使用

news2024/11/24 18:40:52

文章目录

  • 前言
  • 一、交叉编译i2c_tool
  • 二、板子上使用i2c_tool
  • 三、为什么不需要编写驱动也能够访问到对应设备
  • 四、命令行使用i2_tool操作AP3216模块
  • 五、使用i2c_tool代码操作IIC设备
  • 六、相关函数讲解
    • 1.open_i2c_dev
    • 2.int set_slave_addr
  • 七、具体代码编写
  • 总结


前言

本篇文章将带大家学习i2c_tool这个工具,有了这个工具无需驱动程序我们也可以访问到iic设备。

一、交叉编译i2c_tool

首先需要得到i2c_tool的源码:
在终端执行下面的命令:

git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git

修改makefile中的工具链:
在这里插入图片描述
这里需要修改为arm的工具链,这样我们才能到板子上面使用。

执行make:
在这里插入图片描述
编译生成了include文件夹和lib文件夹:
在这里插入图片描述
将include文件夹中的头文件和lib文件夹中的动静态库都拷贝到系统目录下:

查看系统目录的路径:

echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v -

在这里插入图片描述
拷贝到对应的目录:
拷贝头文件:

在这里插入图片描述
拷贝库文件:
在这里插入图片描述
把对应的库拷贝到板子上:
在这里插入图片描述

二、板子上使用i2c_tool

使用i2cdetect -l 命令可以检测到板子上有多少个i2c控制器:
在这里插入图片描述
使用i2cdetect -y -a 0命令可以检测到对应i2c总线上挂载的设备:
在这里插入图片描述
在这里插入图片描述
这里的UU代表内核中已经有了这个驱动,显示的是数值的话就代表内核中没有这个驱动。

三、为什么不需要编写驱动也能够访问到对应设备

我们的正常思维都是一个设备需要有一个对应的驱动程序,那么这个i2c_tool到底是怎么样操作到设备的呢?

这里使用百问网的一张图片来解释说明:
在这里插入图片描述
1.Linux 内核已经提供了 i2c-dev 模块,它允许用户空间应用程序通过特定的文件系统接口进行 I2C 通信。这个模块负责处理底层的 I2C 总线传输,并将读写请求转发到相应的 I2C 设备上。因此,基于 i2c-dev 模块的工具(如 i2c_tool)可以直接利用这个模块提供的接口进行硬件访问。

2.文件系统接口:i2c-dev 模块将 I2C 总线和设备映射为文件系统中的特殊文件。通过打开这些文件,并使用读写操作对其进行访问,用户空间应用程序可以与 I2C 设备进行通信。i2c_tool 就是通过读写这些特殊文件实现对硬件模块的操作。

3.统一的接口:通过使用 i2c-dev 模块提供的文件系统接口,i2c_tool 可以以统一的方式与不同的 I2C 设备进行通信。无论是操作传感器、存储器、显示器还是其他类型的设备,只需提供正确的设备地址和命令,并在 i2c_tool 中执行适当的读写操作即可。

四、命令行使用i2_tool操作AP3216模块

AP3216是一种集成了环境光传感器(ALS)、红外光传感器(IR)和距离传感器(PS)的数字化模块。它可用于测量环境光强度、接近物体距离和红外光反射强度等应用。

以下是一些关于AP3216模块的基本特性和功能:

具有三个传感器:

环境光传感器(ALS):测量环境光强度,并提供数字输出结果。
红外光传感器(IR):测量红外光强度,并提供数字输出结果。
距离传感器(PS):测量物体与传感器之间的距离,并提供数字输出结果。

下面我们使用i2c_tool来直接操作AP3216:

操作步骤:
复位:往寄存器 0 写入 0x4
使能:往寄存器 0 写入 0x3
读光强:读寄存器 0xC、0xD 得到 2 字节的光强
读距离:读寄存器 0xE、0xF 得到 2 字节的距离值

这样的话就可以将具体的数值读取出来了:
在这里插入图片描述

五、使用i2c_tool代码操作IIC设备

使用命令行来操作IIC设备是非常简单的,但是有的时候也需要我们会使用i2c_tool的源码来对IIC设备进行操作:

流程图(来自百问网):

下面这些函数的原型可以在i2c_tool源码中查看到:
在这里插入图片描述

六、相关函数讲解

1.open_i2c_dev

i2cbus 是要打开的 I2C 总线的编号,filename 是传入的缓冲区,用于存储设备文件路径。size 是缓冲区的大小,quiet 是一个标志,指示是否抑制错误输出。

int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet);

2.int set_slave_addr

函数返回类型为 int,接收的参数包括 file(文件描述符),address(要设置的从设备地址)和 force(强制设置地址的标志)。

int set_slave_addr(int file, int address, int force);

七、具体代码编写


#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "i2cbusses.h"


#define I2C_BUS      0
#define AP3216C_ADDR 0x1e

static int fd;

int ap3216c_init(void)
{
	char buf[100];
	int err;
	struct i2c_rdwr_ioctl_data rdwr;
	struct i2c_msg msgs[1];
	int nmsgs_sent;
	
	fd = open_i2c_dev(I2C_BUS, buf, sizeof(buf), 0);
	if (fd < 0)
	{
		printf("can not open i2c bus %d\n", I2C_BUS);
		return fd; /* err */
	}

	err = set_slave_addr(fd, AP3216C_ADDR, 1);
	if (err)
	{
		printf("can not set slave addr 0x%x\n", AP3216C_ADDR);
		return err;
	}

	/* reset ap3216c */
	msgs[0].addr  = AP3216C_ADDR;
	msgs[0].flags = 0;      /* 写:0, 读:I2C_M_RD */
	msgs[0].len   = 2;
	msgs[0].buf   = buf;
	buf[0] = 0;
	buf[1] = 4;

	rdwr.msgs = msgs;
	rdwr.nmsgs = 1;
	nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
	if (nmsgs_sent != 1)
	{
		printf("can not reset ap3216c\n");
		return -1;  /* err */
	}

	/* enable ap3216c */
	msgs[0].addr  = AP3216C_ADDR;
	msgs[0].flags = 0;      /* 写:0, 读:I2C_M_RD */
	msgs[0].len   = 2;
	msgs[0].buf   = buf;
	buf[0] = 0;
	buf[1] = 3;

	rdwr.msgs = msgs;
	rdwr.nmsgs = 1;
	nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
	if (nmsgs_sent != 1)
	{
		printf("can not enable ap3216c\n");
		return -1;  /* err */
	}
	
	return 0;
}

int ap3216c_read_light(void)
{
	struct i2c_rdwr_ioctl_data rdwr;
	struct i2c_msg msgs[2];
	int nmsgs_sent;

	char buf_tx[1];
	char buf_rx[2];

	int light;

	/* 发送寄存器地址 */
	msgs[0].addr  = AP3216C_ADDR;
	msgs[0].flags = 0;      /* 写:0, 读:I2C_M_RD */
	msgs[0].len   = 1;
	msgs[0].buf   = buf_tx;
	buf_tx[0] = 0xc;

	msgs[1].addr  = AP3216C_ADDR;
	msgs[1].flags = I2C_M_RD;      /* 写:0, 读:I2C_M_RD */
	msgs[1].len   = 2;
	msgs[1].buf   = buf_rx;

	rdwr.msgs = msgs;
	rdwr.nmsgs = 2;
	nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
	if (nmsgs_sent != 2)
	{
		printf("can not read ap3216c light\n");
		return -1;  /* err */
	}

	light = (buf_rx[1]<<8) | buf_rx[0];
	
	return light;
}

int ap3216c_read_distance(void)
{
	struct i2c_rdwr_ioctl_data rdwr;
	struct i2c_msg msgs[2];
	int nmsgs_sent;

	char buf_tx[1];
	char buf_rx[2];

	int distance;

	/* 发送寄存器地址 */
	msgs[0].addr  = AP3216C_ADDR;
	msgs[0].flags = 0;		/* 写:0, 读:I2C_M_RD */
	msgs[0].len   = 1;
	msgs[0].buf   = buf_tx;
	buf_tx[0] = 0xe;

	msgs[1].addr  = AP3216C_ADDR;
	msgs[1].flags = I2C_M_RD;	   /* 写:0, 读:I2C_M_RD */
	msgs[1].len   = 2;
	msgs[1].buf   = buf_rx;

	rdwr.msgs = msgs;
	rdwr.nmsgs = 2;
	nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
	if (nmsgs_sent != 2)
	{
		printf("can not read ap3216c light\n");
		return -1;	/* err */
	}

	distance = ((buf_rx[1] & 0x3F)<<4) | (buf_rx[0] & 0xf);
	
	return distance;
}





#include <stdio.h>
#include <unistd.h>
#include "ap3216c_lib.h"

int main(int argc, char **argv)
{
	int err; 
	int light, distance;
	int cnt = 0;
	
	err = ap3216c_init();
	if (err)
	{
		printf("ap3216c_init err : %d\n", err);
	}

	while (1)
	{
		light = ap3216c_read_light();	
		distance = ap3216c_read_distance();
		printf("%03d: light = %d, distance = %d\n", cnt, light, distance);
		cnt++;
		sleep(5);
	}


	return 0;
}


总结

这篇文章我们就讲解到这里,i2c_tool工具还是非常强大的,大家有必要掌握一下。

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

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

相关文章

精益生产对制造业真的那么重要吗?

说到底是精益生产值不值得的问题。 重要且可得&#xff0c;那它就值得。国内的很多制造企业之所以对“精益生产”持怀疑甚至否度态度&#xff0c;大都经历过实施过程中的“水土不服”难题。抛砖引玉讲一下&#xff1a; 1、精益生产的最典型案例 1991年&#xff0c;在当时整个…

架构训练营笔记:可扩展设计

可扩展 复杂度模型 业务复杂度&#xff1a;业务固有的复杂度&#xff0c;主要体现为难以理解、难以扩展&#xff0c;例如业务数量多&#xff08;微信&#xff09;、业务流程长&#xff08;支付宝&#xff09;、业务之间关系复杂&#xff08;例如ERP&#xff09;。 质量复杂度…

基于单片机的智能空调系统的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前水温&#xff0c;定时提醒&#xff0c;水量变化DS18B20检测当前水体温度&#xff1b;水位传感器检测当前水位&#xff1b;继电器驱动加热片进行水温加热&#xff1b;定时提醒喝水&#xff0c;蜂鸣器报警&#x…

「网络编程」应用层协议_ HTTP协议学习及深入理解

「前言」文章内容大致是应用层协议的HTTP协议讲解。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「句子分享」 俗话说&#xff0c;开弓没有回头箭&#xff0c;唯有箭折、箭落、箭中靶子三种结果而已。 ——江晓英《苏东坡&#xf…

开源代码分享(6)—考虑实时市场联动的电力零售商鲁棒定价策略(附matlab代码)

摘要&#xff1a;电力零售商作为连接电力批发市场与零售市场的桥梁&#xff0c;是电力市场化改革中的重要主体&#xff0c;其经营效率直接决定了市场化改革的成败。然而电力零售商在运营过程中面临着用电量需求和价格双重不确定性的市场风险&#xff0c;亟需通过优化市场行为以…

Qt实现画板绘制椭圆

Qt在窗体中绘图在paintEvent函数中进行,使用QPainter类进行窗体绘制 如果只是简单的在paintevent中向画布绘制椭圆,由于实时绘制的许多个椭圆重合在一起,就会出现下面的情况 你可以在每次绘制椭圆之前调用清空画布 myPix->fill(Qt::white);但是又会出现下面的情况,无法…

一篇万字博客带你入门layUI

今日金句 心里种花&#xff0c;人生才不会荒芜 文章目录 一、什么是layui二、layui、easyui与bootstrap的对比2.1 layui和bootstrap对比&#xff08;这两个都属于UI渲染框架&#xff09;2.2 layui和easyui对比 三、layui入门3.1 引入3.2 入门案例&#xff1a;点击弹出框3.3 经…

数学建模———层次分析法及其matlab语法,函数和代码实现

层次分析法思想登场 建模比赛中最基础的模型之一&#xff0c;其主要用于解决评价类问题&#xff08;例如&#xff1a;选择那种方案最好&#xff0c;哪位运动员或者员工表现的更优秀。&#xff09; 评价类问题字眼&#xff1a; 评价的目标是什么&#xff1f;达到这个目标有那…

flutter开发实战-dio文件下载实现

flutter开发实战-dio文件下载实现 在开发中&#xff0c;需要下载文件&#xff0c;这里使用的是dio dio 是一个强大的 Dart HTTP 请求库&#xff0c;支持全局配置、Restful API、FormData、拦截器、 请求取消、Cookie 管理、文件上传/下载、超时以及自定义适配器等。 一、引入d…

apache下载

Apache VS17 binaries and modules download php下载地址 PHP For Windows: Home windows.php.net - /downloads/releases/archives/ 历史版本下载 php下载 https://windows.php.net/downloads/releases/archives/php-5.6.37-Win32-VC11-x64.zip https://www.apachehaus.com/…

代码随想录day14

这里推荐这三道题先熟悉二叉树的三种遍历方式 144. 二叉树的前序遍历&#xff08;中->左->右) 根左右。前序遍历首先访问根结点然后遍历左子树&#xff0c;最后遍历右子树。在遍历左、右子树时&#xff0c;仍然先访问根节点&#xff0c;然后遍历左子树&#xff0c;最后…

如何在云中实现安全与合规的规模化?亚马逊云科技给出了答案

在亚马逊云科技&#xff0c;为满足客户不断变化的需求&#xff0c;亚马逊云科技持续创新与迭代&#xff0c;设计的服务能帮助客户满足最严格的安全和合规性要求。针对安全相关工作&#xff0c;亚马逊云科技服务团队与Amazon Security Guardians云守护者项目密切配合&#xff0c…

【计算机视觉】80 TB!58.5 亿!世界第一大规模公开图文数据集 LAION-5B 解读

文章目录 一、导读二、数据集背景信息2.1 图文对数据集2.2 图像数据集 三、LAION-5B有什么3.1 子集3.2 开源模型3.3 KNN index/web界面 四、LAION可以做什么任务4.1 图文匹配及多模态预训练4.2 生成任务4.3 分类任务4.4 其他任务 五、总结 一、导读 继去年 LAION-400M 这个史上…

Android Jetpack Compose多平台用于Android和IOS

Android Jetpack Compose多平台用于Android和IOS JetBrains和外部开源贡献者已经努力工作了几年时间来开发Compose Multiplatform&#xff0c;并最近发布了适用于iOS的Alpha版本。自然地&#xff0c;我们对其功能进行了测试&#xff0c;并决定通过使用该框架在iOS上运行我们的…

leetcode47. 全排列 II 回溯剪枝的细节问题

题目描述&#xff1a; 1、思路 作为回溯算法的经典问题&#xff0c;常用的方法是&#xff0c;每次dfs前先判断是否达到临界条件&#xff0c;满足条件则加入结果集并return。通过循环和dfs来构建树&#xff0c;查找出全部满足条件的集合。 例如本题&#xff0c;如1&…

dp动态规划详解下

dp动态规划详解上&#xff1a;https://blog.csdn.net/weixin_73936404/article/details/131527247?spm1001.2014.3001.5501 目录 dp动态规划详解上&#xff1a;https://blog.csdn.net/weixin_73936404/article/details/131527247?spm1001.2014.3001.5501 【案例1】 【题目描…

强度(极限强度、屈服强度)、韧性材料与脆性材料(韧性材料与脆性材料的强度、为什么脆性材料在压缩时比在拉伸时更坚固?)、材料的延展性、韧性、弹性

1.强度 强度&#xff08;Strength&#xff09;是材料可以承受的应力的量度&#xff0c;通常使用极限强度&#xff08;Ultimate strength&#xff09;和屈服强度&#xff08;Yield strength&#xff09;来定义材料的强度-极限。 材料的极限抗拉强度定义为在拉伸试验过程中达到的…

windows 编译libyuv

一、libyuv下载 git clone https://chromium.googlesource.com/external/libyuv 二、libjpeg-turbo下 git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git 三、编译可以参考 BUILDING.md 需要环境&#xff1a; VS2019 CMake YASM 启动vs工具 编译&#xff1…

js模块化开发

◼ 到底什么是模块化、模块化开发呢&#xff1f;  事实上模块化开发最终的目的是将程序划分成一个个小的结构&#xff1b;  这个结构中编写属于自己的逻辑代码&#xff0c;有自己的作用域&#xff0c;定义变量名词时不会影响到其他的结构&#xff1b;  这个结构可以将自己…

SAP S4 Hana 下面ACDOCA 凭证行字段增强创建过程

网上找到这个类下面是可以新增增强的 现在需要在如下位置建立四代增强点 保存以后会出现下面的增强项 保存激活后&#xff0c;完成在源程序中增加了一个4代显式增强点.上面步骤只是在程序中建立了一个增强点&#xff0c;并没有执行什么动作&#xff0c;就相当于建立一个容器。如…