Linux应用开发基础知识——I2C应用编程(十三)

news2024/12/25 2:16:58

一、无需编写驱动程序即可访问 I2C 设备

        APP 访问硬件肯定是需要驱动程序的,对于 I2C 设备,内核提供了驱动程序 drivers/i2c/i2c-dev.c,通过它可以直接使用下面的 I2C 控制器驱动程序来访问 I2C 设备。

i2c-tools 是一套好用的工具,也是一套示例代码。

1.体验 I2C-Tools

        使用一句话概括 I2C 传输:APP 通过 I2C Controller 与 I2C Device 传 输数据。 所以使用 I2C-Tools 时也需要指定:

         哪个 I2C 控制器(或称为 I2C BUS、I2C Adapter)

         哪个 I2C 设备(设备地址)

         数据:读还是写、数据本身

(1)交叉编译

        配置环境:vim ~/.bashrc

export ARCH=arm
export CROSS_COMPILE= arm-buildroot-linux-gnueabihf-gccexport PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin

        修改 I2C-Tools 的 Makefile 指定交叉编译工具链

CC ?= gcc
AR ?= ar
STRIP ?= strip

        改为(指定交叉编译工具链前缀, 去掉问号):

CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
STRIP = $(CROSS_COMPILE)strip

        在 Makefile 中,“?=”在第一次设置变量时才会起效果,如果之前设置过 该变量,则不会起效果。

(2)执行 make

        执行 make 时,是动态链接,需要把 libi2c.so 也放到单板上

        想静态链接的话,执行:make USE_STATIC_LIB=1

(3)用法

         i2cdetect:I2C 检测

// 列出当前的 I2C Adapter(或称为 I2C Bus、I2C Controller)
i2cdetect -l
// 打印某个 I2C Adapter 的 Functionalities, I2CBUS 为 0、1、2 等整数
i2cdetect -F I2CBUS
// 看看有哪些 I2C 设备, I2CBUS 为 0、1、2 等整数
i2cdetect -y -a I2CBUS
// 效果如下
# i2cdetect -l
i2c-1 i2c STM32F7 I2C(0x40013000) I2C adapter
i2c-2 i2c STM32F7 I2C(0x5c002000) I2C adapter
i2c-0 i2c STM32F7 I2C(0x40012000) I2C adapter
# i2cdetect -F 0
Functionalities implemented by /dev/i2c-0:
I2C yes
SMBus Quick Command yes
SMBus Send Byte yes
SMBus Receive Byte yes
SMBus Write Byte yes
SMBus Read Byte yes
SMBus Write Word yes
SMBus Read Word yes
SMBus Process Call yes
SMBus Block Write yes
SMBus Block Read yes
SMBus Block Process Call yes
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes
// --表示没有该地址对应的设备, UU 表示有该设备并且它已经有驱动程序,
// 数值表示有该设备但是没有对应的设备驱动
# i2cdetect -y -a 0 
 0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 00 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- 1e --
20: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

(3)i2cget:I2C 读

  使用说明:

# i2cget
Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]
 I2CBUS is an integer or an I2C bus name
 ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
 MODE is one of:
 b (read byte data, default)
 w (read word data)
 c (write byte/read byte)
Append p for SMBus PEC

  使用示例:

// 读一个字节: I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
i2cget -f -y I2CBUS CHIP-ADDRESS
// 读某个地址上的一个字节: 
// I2CBUS 为 0、1、2 等整数, 表示 I2C Bus
// CHIP-ADDRESS 表示设备地址
// DATA-ADDRESS: 芯片上寄存器地址
// MODE:有 2 个取值, b-使用`SMBus Read Byte`先发出 DATA-ADDRESS, 再读一个字节, 中间无
P 信号
// c-先 write byte, 在 read byte,中间有 P 信号
i2cget -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS MODE
// 读某个地址上的 2 个字节: 
// I2CBUS 为 0、1、2 等整数, 表示 I2C Bus
// CHIP-ADDRESS 表示设备地址
// DATA-ADDRESS: 芯片上寄存器地址
// MODE:w-表示先发出 DATA-ADDRESS,再读 2 个字节
i2cget -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS MODE

(4)i2cset:I2C 写

  使用说明:

# i2cset
Usage: i2cset [-f] [-y] [-m MASK] [-r] [-a] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE]
... [MODE]
 I2CBUS is an integer or an I2C bus name
 ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)
 MODE is one of:
 c (byte, no value)
 b (byte data, default)
 w (word data)
 i (I2C block data)
 s (SMBus block data)
Append p for SMBus PEC

  使用示例:

// 写一个字节: I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
 // DATA-ADDRESS 就是要写的数据
 i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS
 
 // 给 address 写 1 个字节(address, value):
 // I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
 // DATA-ADDRESS: 8 位芯片寄存器地址; 
 // VALUE: 8 位数值
 // MODE: 可以省略,也可以写为 b
 i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE [b]
 
 // 给 address 写 2 个字节(address, value):
 // I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
 // DATA-ADDRESS: 8 位芯片寄存器地址; 
 // VALUE: 16 位数值
 // MODE: w
 i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE w
 
 // SMBus Block Write:给 address 写 N 个字节的数据
 // 发送的数据有:address, N, value1, value2, ..., valueN
 // 跟`I2C Block Write`相比, 需要发送长度 N
 // I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
 // DATA-ADDRESS: 8 位芯片寄存器地址; 
 // VALUE1~N: N 个 8 位数值
 // MODE: s
 i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE1 ... VALUEN s
 
 // I2C Block Write:给 address 写 N 个字节的数据
 // 发送的数据有:address, value1, value2, ..., valueN
 // 跟`SMBus Block Write`相比, 不需要发送长度 N
 // I2CBUS 为 0、1、2 等整数, 表示 I2C Bus; CHIP-ADDRESS 表示设备地址
 // DATA-ADDRESS: 8 位芯片寄存器地址; 
 // VALUE1~N: N 个 8 位数值
 // MODE: i
 i2cset -f -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE1 ... VALUEN i

(5)i2ctransfer:I2C 传输(不是基于 SMBus)

  使用说明:

# i2ctransfer
Usage: i2ctransfer [-f] [-y] [-v] [-V] [-a] I2CBUS DESC [DATA] [DESC [DATA]]...
 I2CBUS is an integer or an I2C bus name
 DESC describes the transfer in the form: {r|w}LENGTH[@address]
 1) read/write-flag 2) LENGTH (range 0-65535) 3) I2C address (use last one if omit
ted)
 DATA are LENGTH bytes for a write message. They can be shortened by a suffix:
 = (keep value constant until LENGTH)
 + (increase value by 1 until LENGTH)
 - (decrease value by 1 until LENGTH)
 p (use pseudo random generator until LENGTH with value as seed)
Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):
 # i2ctransfer 0 w1@0x50 0x64 r8
Example (same EEPROM, at offset 0x42 write 0xff 0xfe ... 0xf0):
 # i2ctransfer 0 w17@0x50 0x42 0xff

  使用举例:

// Example (bus 0, read 8 byte at offset 0x64 from EEPROM at 0x50):
# i2ctransfer -f -y 0 w1@0x50 0x64 r8
// Example (bus 0, write 3 byte at offset 0x64 from EEPROM at 0x50):
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3
// Example 
// first: (bus 0, write 3 byte at offset 0x64 from EEPROM at 0x50)
// and then: (bus 0, read 3 byte at offset 0x64 from EEPROM at 0x50)
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3 r3@0x50 
# i2ctransfer -f -y 0 w9@0x50 0x64 val1 val2 val3 r3 //如果设备地址不变,后面的设备地址可
省略

2.使用 I2C-Tools 操作传感器 AP3216C

开发板上有光感芯片 AP3216C:

AP3216C 是红外、光强、距离三合一的传感器,以读出光强、距离值为例,步骤如下:

         复位:往寄存器 0 写入 0x4

         使能:往寄存器 0 写入 0x3

         读光强:读寄存器 0xC、0xD 得到 2 字节的光强

         读距离:读寄存器 0xE、0xF 得到 2 字节的距离值 AP3216C 的设备地址是 0x1E,假设节在 I2C BUS0 上,操作命令如下: 

(1)使用 SMBus 协议 

i2cset -f -y 0 0x1e 0 0x4
i2cset -f -y 0 0x1e 0 0x3
i2cget -f -y 0 0x1e 0xc w
i2cget -f -y 0 0x1e 0xe w

(2)使用 I2C 协议

i2ctransfer -f -y 0 w2@0x1e 0 0x4
i2ctransfer -f -y 0 w2@0x1e 0 0x3
i2ctransfer -f -y 0 w1@0x1e 0xc r2
i2ctransfer -f -y 0 w1@0x1e 0xe r2

(3) I2C-Tools 访问 I2C 设备的 2 种方式

        I2C-Tools 可以通过 SMBus 来访问 I2C 设备,也可以使用一般的 I2C 协议 来访问 I2C 设备

        使用一句话概括 I2C 传输:APP 通过 I2C Controller 与 I2C Device 传输数据。

        在 APP 里,有这几个问题:

怎么指定 I2C 控制器?

         i2c-dev.c 为每个 I2C 控制器(I2C Bus、I2C Adapter)都生成一个设备节 点:/dev/i2c-0、/dev/i2c-1 等等;

         open 某个/dev/i2c-X 节点,就是去访问该 I2C 控制器下的设备;

怎么指定 I2C 设备?

        通过 ioctl 指定 I2C 设备的地址

        ioctl(file, I2C_SLAVE, address)

                 如果该设备已经有了对应的设备驱动程序,则返回失败。

        ioctl(file, I2C_SLAVE_FORCE, address)

                 如果该设备已经有了对应的设备驱动程序但是还是想通过 i2c-dev 驱 动来访问它,则使用这个 ioctl 来指定 I2C 设备地址。

怎么传输数据?

        两种方式:

                 一般的 I2C 方式:ioctl(file, I2C_RDWR, &rdwr)

                 SMBus 方式:ioctl(file, I2C_SMBUS, &args)

3.源码流程分析 

(1)使用 I2C 方式

示例代码:i2ctransfer.c

(2)使用 SMBus 方式

示例代码:i2cget.c、i2cset.c

 

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

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

相关文章

毅速:复杂零件制造首选3D打印

确金属3D打印技术在制造行业的应用日益广泛,为制造业带来了巨大的变革和机遇。这种增材制造技术相较于传统制造工艺具有许多优势,尤其在制造复杂形状零件方面表现出色。 传统制造工艺在制造复杂形状零件时往往面临诸多挑战,如加工难度大、周期…

SuperMap iDesktopX如何获取简单线的起终端点及坐标

作者:超图研究院技术支持中心-于丁 SuperMap iDesktopX如何获取简单线的起终端点及坐标 在GIS行业应用中,线数据的端点坐标有非常多的用处。 定位和可视化:线数据端点坐标可以用于定位和可视化线要素在空间中的位置。这对于地图制作、规划和…

中文地址命名实体识别训练和预测

效果 github项目地址 https://github.com/taishan1994/pytorch_bert_bilstm_crf_ner 下载项目 放在这个位置“F:\Python\github\ultralytics-main\submain\pytorch_bert_bilstm_crf_ner-main” 训练和预测步骤 1、下载数据集 从github项目可以找到数据集下载地址 https:…

Youtube0播放?运营教你需要的技巧、策略与工具!

对于有跨境意向的内容创作者或者品牌企业来说,YouTube是因其巨大的潜在受众群和商业价值成为最值得投入变现与营销计划的平台。 据统计,98% 的美国人每月访问 YouTube,近三分之二的人每天访问。但是,YouTube还远未达到过度饱和的…

Python 哈希表的实现——字典

哈喽大家好,我是咸鱼 接触过 Python 的小伙伴应该对【字典】这一数据类型都了解吧 虽然 Python 没有显式名称为“哈希表”的内置数据结构,但是字典是哈希表实现的数据结构 在 Python 中,字典的键(key)被哈希&#x…

处理视频的新工具:UniFab 2.0.0.4 Crack

UniFab这是一个用于处理视频的新工具,可以帮助您像专业人士一样获得结果,事实上,它可以确保在项目的任何设备上完美播放,所以,来认识一下 UniFab - 一款功能强大且方便的视频编辑器和转换器,但另一方面&…

【Spring日志】

一.日志作用 1.定位和发现问题 这是日志的主要用途,通过查看日志,我们可以定位问题发生的位置,从而快速的发现问题,分析问题. 2.系统监控 监控几乎是一个成熟系统的标配,我们可以通过日志记录这个系统的运行状态,比如记录方法的响应时间,响应状态,通过设置不同的规则,超过阈值就…

硅光子,缘何打造量子科技的下一个十年?

/目录/ 一、硅光子技术将率先实现室温、容错量子计算机 二、用于量子科技的硅光子器件 2.1. 单光子源 2.2. 光子探测器 2.3. 波分复用技术 2.4. 低温技术 2.5. 芯片互连 三、可拓展的量子信息应用 3.1. 多光子和高维应用 3.2. 量子纠错 3.3. 量子密钥分发 3.4. 量子…

Android runtime层是如何通过缩减代码来缩减内存的

文章目录 前言:Android 在设备上改进内存的秘密优化编译器101代码大小改进消除写入障碍隐式暂停检查合并回调其他优化改进代码下沉循环优化消除死代码 – SimplifyAlwaysThrows加载存储消除 – 使用 try catch 块加载存储消除 – 使用释放/获取操作新的内联启发式不…

LiveVIS视图库1400-如何切换数据库?默认使用的数据库是什么?如何切换到Mysql/MariaDB?

LiveVIS视图库1400-如何切换数据库?默认使用的数据库是什么?如何切换到Mysql/MariaDB? 1、切换成Mysql/Mariadb数据库1.1 连接数据库1.2 创建数据库实例1.3 配置.ini文件1.4 重启完成切换 1、切换成Mysql/Mariadb数据库 LiveVIS 默认使用 sqlite3 文件…

无需API开发,钱方QFPay连接营销系统和广告推广平台

随着电子商务市场的不断发展,企业需要集成各种业务系统,以提高业务效率和降低运营成本。钱方QFPay提供了一种创新的解决方案,帮助企业实现系统间的连接和集成,无需进行复杂的API开发。除了电商系统和客服系统,钱方还能…

PHP5.3 + Apache2.2 + Xdebug2.1.2环境并集成至PHPStrom全流程(解决使用最好的语言前的痛点问题)

文章目录 问题背景安装流程PHP安装配置PHPApache安装及配置PHPStrom集成PHP环境进行PHP开发 问题背景 由于公司陈旧项目的重新启动,现需要对该项目开发微信登录模块,本人是写 Java 的,但本着程序员终身学习、不惧新事物的特点,现…

CCFCSP试题编号:202305-2试题名称:矩阵运算

只要懂如何进行矩阵乘法就好了&#xff0c;和注意一点数的大小范围就ok了&#xff01; #include <iostream> using namespace std;const int N 10010, D 30; long long tmp[D][D], ans[N][N]; int n, d; int Q[N][D], K[N][D], V[N][D], W[N]; int main() {cin >&g…

2048 数字合成大作战,Android小游戏开发

A. 项目描述 《2048》是一款经典的益智小游戏&#xff0c;它的目标是通过合并相同数字来达到2048这个最高分。 该游戏规则简单&#xff0c;玩家需要通过滑动屏幕来移动方块&#xff0c;相同数字的方块会合并成一个新的数字方块。这样的简单操作让人可以轻松上手。 《2048》小…

室内卫星定位信号弱?——看时间服务器与GNSS模拟器如何实现区域内可靠的室内定位!

方案介绍 GNSS是当前最常用、覆盖最广泛、效率最高的定位导航技术&#xff0c;几乎各个领域都依赖它。然而&#xff0c;在室内或地下&#xff0c;GNSS信号通常非常弱甚至不可用。德思特采用时间服务器与GNSS模拟器相结合&#xff0c;提供了一种基于区域的室内定位方案。这个方…

笔尖笔帽检测4:C++实现笔尖笔帽检测算法(含源码 可是实时检测)

笔尖笔帽检测4&#xff1a;C实现笔尖笔帽检测算法(含源码 可是实时检测) 目录 笔尖笔帽检测4&#xff1a;C实现笔尖笔帽检测算法(含源码 可是实时检测) 1.项目介绍 2.笔尖笔帽关键点检测方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下而上)方法&#xff1a; 3.笔尖笔…

针对CSP-J/S的每日一练:Day 11

一、审题 题目描述 给定两个大小分别为 m m m 和 n n n 的正序&#xff08;从小到大&#xff09;数组 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2。请你找出并返回这两个正序数组的中位数。 算法的时间复杂度应该为 O ( l o g ( m n ) ) O(log (mn)) O(log(mn)) 。…

7天高效处理500万件订单,母婴巨头Babycare的人效提升之路

随着出生率下降&#xff0c;新生儿人口不断减少&#xff0c;母婴市场竞争愈加激烈。与此同时&#xff0c;越来越多90后、95后成为父母&#xff0c;新的消费需求和触媒习惯让各大母婴品牌不再仅仅专注于在传统的线下零售渠道争得一席之地&#xff0c;而是逐步转型为以数字化驱动…

【腾讯云HAI】都2023年了,HAI没玩过AIGC?

:::info 腾讯云高性能应用服务(Hyper Application lnventor&#xff0c;HA)&#xff0c;是一款面向 Al、科学计算的 GPU 应用服务产品&#xff0c;为开发者量身打造的澎湃算力平台。无需复杂配置&#xff0c;便可享受即开即用的GPU云服务体验。在 HA] 中&#xff0c;根据应用智…

django(千锋教育)

创建一个django项目 官网下载python最新版本 配置到环境变量中 打开intlij编辑器 创建django项目 安装django&#xff1a;pip install django 创建django项目: django-admin startproject django01 创建djangoAPP&#xff1a;python manage.py startapp App 启动&#xff1a…