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

一、无需编写驱动程序即可访问 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 nameADDRESS 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 nameADDRESS 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: 可以省略,也可以写为 bi2cset -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: wi2cset -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: si2cset -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: ii2cset -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 nameDESC 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.hqwc.cn/news/214544.html

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

相关文章

有没有免费可用的亚马逊两步验证器软件?

两步验证(Two-Step Verification)是一种可以增加账号安全性的有效方式,启用两步验证后,即使你的密码被泄露也不影响,因为除了输入密码外,用户还需要提供二步验证码,通常是通过手机短信、身份验证…

C/C++ 开发SCM服务管理组件

SCM(Service Control Manager)服务管理器是 Windows 操作系统中的一个关键组件,负责管理系统服务的启动、停止和配置。服务是一种在后台运行的应用程序,可以在系统启动时自动启动,也可以由用户或其他应用程序手动启动。…

免杀原理(php)

免杀原理 0x01 前言 何为免杀,免杀就是一种逃脱杀毒软件查杀的方法,免杀的目的就是绕过“墙”,去执行危险的操作。那么如何绕过这堵“墙”,就是免杀的本质。有句俗话说得好“知己知彼,百战不殆”,想要用好…

JavaScript实现动态背景颜色

JavaScript实现动态背景颜色 前言实现过程HTML实现过程CSS实现过程JS实现过程全部源码 前言 本文主要讲解JavaScript如何实现动态背景颜色,可以根据颜色选择器选择的颜色而实时更新到背景中,如下图所示。 当我们在颜色选择器中改变颜色时,会…

渲染农场渲染一分钟动画需要多少钱?需要渲染多少时间?

现在很公司都开始使用渲染农场渲染动画,但是还是有很多人不知道渲染农场渲染动画需要多少钱,需要渲染多少时间。在这篇文章中我们将为你一一解答,为你提供一个清晰的参考。 渲染农场的收费通常是按照渲染的使用时间收费,渲染十分…

网络运维与网络安全 学习笔记2023.11.24

网络运维与网络安全 学习笔记 第二十五天 今日目标 DHCP中继代理、三层交换机DHCP、子网划分的原理、子网划分的应用 项目需求分析、技术方案选型、网络拓扑绘制 基础交换网络设计、内网优化、连接外网服务器 DHCP中继代理 DHCP中继概述 场景: DHCP客户端与DH…

Vatee万腾科技新高峰:Vatee前瞻性创新的数字化之力

Vatee万腾科技,一家以前瞻性创新为核心驱动力的数字化引领者,正迈向新的高峰。其在科技领域的卓越表现不仅体现在技术实力上,更展现在对未来的深刻洞察和独到思考上。 在Vatee的科技舞台上,前瞻性创新如一道独特的光芒&#xff0c…

上门预约小程序开发优势

想要放松身心,享受按摩的舒适感?那就需要一个专业的按摩师来上门服务。我们开发的预约按摩小程序app系统,汇聚各类上门按摩服务,包括推拿SPA、小儿推拿、中医等,为您提供高价值、高标准的养生健康体验。24小时随时提供…

U9二次开发之轻量服务项目开发

最近公司要开发一个下载图纸的U9轻量级接口,轻量级接口就是restful api,可以直接通过get、post等方式调用,参数的传送和结果的返回都使用JSON格式,用起来比Webservice接口爽多了。 如果是开发新的接口,我建议都用轻量…

机器学习/sklearn 笔记:K-means,kmeans++,MiniBatchKMeans,二分Kmeans

1 K-means介绍 1.0 方法介绍 KMeans算法通过尝试将样本分成n个方差相等的组来聚类,该算法要求指定群集的数量。它适用于大量样本,并已在许多不同领域的广泛应用领域中使用。KMeans算法将一组样本分成不相交的簇,每个簇由簇中样本的平均值描…

如何使用 TikTok 提高亚马逊销量

TikTok(及其受众)比以往任何时候都更大。爱它或恨它,它的影响力都难以忽视。 作为2021 年下载量第一的应用程序,拥有超过 10 亿用户,TikTok 对于希望直接与客户建立联系的品牌来说已经变得至关重要。循环、无限滚动和…

多线程Thread(初阶三:线程的状态及线程安全)

目录 一、线程的状态 二、线程安全 一、线程的状态 1.NEW Thread:对象创建好了,但是还没有调用 start 方法在系统中创建线程。 2.TERMINATED: Thread 对象仍然存在,但是系统内部的线程已经执行完毕了。 3.RUNNABLE: 就绪状态&…