LinuxI2C应用编程——I2C-Tools的使用

news2024/11/18 2:33:06

文章目录

  • I2C 硬件框架
  • I2C 软件框架
  • I2C协议(传输数据的格式)
    • 写操作
    • 读操作
    • I2C 信号
  • SMBus 协议
    • 概述
    • 硬件和软件上的区别
    • SMBus 协议分析
      • 符号的含义
      • SMBus Quick Command
      • SMBus Receive Byte
      • SMBus Send Byte
      • SMBus Read Byte
      • SMBus Read Word
      • SMBus Write Byte
      • SMBus Write Word
      • SMBus Block Read
      • SMBus Block Write
      • I2C Block Read
      • I2C Block Write
      • SMBus Block Write - Block Read Process Call
      • Packet Error Checking (PEC)
  • I2C 系统的重要结构体
    • i2c_adapter
    • i2c_client
    • i2c_msg
    • 内核传输数据
  • I2C-Tools调试工具
  • I2C-Tools工具的使用
    • 无需编写驱动程序即可访问 I2C 设备
    • 交叉编译 I2C-Tools
    • 用法
      • i2cdetect:I2C检测
      • i2cget:I2C读
      • i2cset:I2C写
      • i2cdump:查看i2c设备所有寄存器的值(和i2cget相同)
      • i2ctransfer:I2C传输(不是基于SMBus)
    • 底层原理
      • 使用I2C-Tools时怎么指定I2C控制器?
      • 使用I2C-Tools时怎么指定I2C设备?(需要知道地址值)
      • 使用I2C-Tools时怎么传输数据?
    • 源码分析
      • 使用I2C方式
      • 使用 SMBus 方式
    • 使用I2C-Tools操作传感器AP3216C
      • 传感器AP3216C介绍
      • I2C-Tools的访问I2C设备的2种方式

I2C 硬件框架

在这里插入图片描述

  • 在一个芯片(SoC)内部,有一个或多个 I2C 控制器
  • 在一个 I2C 控制器上,可以连接一个或多个 I2C 设备
  • I2C 总线只需要 2 条线:时钟线 SCL、数据线 SDA
  • 在 I2C 总线的 SCL、SDA 线上,都有上拉电阻

I2C 软件框架

在这里插入图片描述

I2C的驱动框架包含

  • 设备驱动 Device Driver(负责怎么读写数据)
  • 控制器驱动 Controller Driver(负责传输数据)

I2C协议(传输数据的格式)

写操作

在这里插入图片描述

读操作

在这里插入图片描述

I2C 信号

I2C 协议中数据传输的单位是字节,也就是 8 位。但是要用到 9 个时钟:前面 8 个时钟用来传输 8 数据,第 9 个时钟用来传输回应信号。传输时,先传输最高位(MSB)

  • 开始信号(S):SCL 为高电平时,SDA 山高电平向低电平跳变,开始传送数据。
  • 结束信号(P):SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
  • 响应信号(ACK):接收器在接收到 8 位数据后,在第 9 个时钟周期,拉低SDA
  • SDA 上传输的数据必须在 SCL 为高电平期间保持稳定,SDA 上的数据只能在SCL 为低电平期间变化

I2C 协议信号如下:
在这里插入图片描述
SDA可由主从设备进行控制,所以为了避免争夺线权,实现双向传输,设备的 SDA 中有一个三极管,使用开极/开漏电路(三极管是开极,CMOS 管是开漏,作用一样),这就是 SDA 要使用上拉电阻的原因

SCL 也要使用上拉电阻,在第 9 个时钟之后,如果有某一方需要更多的 时 间 来 处 理 数 据 , 它 可 以 一 直 驱 动 三 极 管 把 SCL 拉 低 。当 SCL 为低电平时候,大家都不应该使用 IIC 总线,只有当 SCL 从低电平变为高电平的时候,IIC 总线才能被使用。当它就绪后,就可以不再驱动三极管,这是上拉电阻把 SCL 变为高电平,其他设备就可以继续使用 I2C 总线了

SMBus 协议

概述

SMBus 是 是 I2C 协议的一个子集

SMBus: System Management Bus,系统管理总线。

SMBus 最初的目的是为智能电池、充电电池、其他微控制器之间的通信链路而定义的。SMBus 也被用来连接各种设备,包括电源相关设备,系统传感器,EEPROM 通讯设备等等。SMBus 为系统和电源管理这样的任务提供了一条控制总线,使用 SMBus 的系统,设备之间发送和接收消息都是通过 SMBus,而不是使用单独的控制线,这样可以节省设备的管脚数。

SMBus 是基于 I2C 协议的,SMBus 要求更严格,SMBus 是 I2C 协议的子集。

硬件和软件上的区别

VDD 的极限值不一样

  • I2C 协议:范围很广,甚至讨论了高达 12V 的情况
  • SMBus:1.8V~5V

最小时钟频率、最大的 Clock Stretching

  • Clock Stretching 含义:某个设备需要更多时间进行内部的处理时,它可以把 SCL 拉低占住 I2C 总线
    -I2C 协议:时钟频率最小值无限制,Clock Stretching 时长也没有限制
    -SMBus:时钟频率最小值是 10KHz,Clock Stretching 的最大时间值也有限制

地址回应(Address Acknowledge):一个 I2C 设备接收到它的设备地址后,是否必须发出回应信号?

  • I2C 协议:没有强制要求必须发出回应信号
  • SMBus:强制要求必须发出回应信号,这样对方才知道该设备的状态:busy,failed,或是被移除了

SMBus 协议明确了数据的传输格式

  • I2C 协议:它只定义了怎么传输数据,但是并没有定义数据的格式,这完全由设备来定义
  • SMBus:定义了几种数据格式(含义更加具体)

REPEATED START Condition(重复发出 S 信号)
比如读 EEPROM 时,涉及 2 个操作:

  • ① 把存储地址发给设备
  • ② 读数据

在写、读之间,可以不发出 P 信号,而是直接发出 S 信号:这个 S 信号就是REPEATED START,如图 10.13 所示
在这里插入图片描述
SMBus Low Power Version:SMBus 也有低功耗的版本

SMBus 协议分析

对于 I2C 协议,它只定义了怎么传输数据,但是并没有定义数据的格式,这完全由设备来定义。
对于 SMBus 协议,它定义了几种数据格式。

因为很多设备都实现了 SMBus,而不是更宽泛的 I2C 协议,所以优先使用SMBus。即使 I2C 控制器没有实现 SMBus,软件方面也是可以使用 I2C 协议来模拟 SMBus。所以:Linux 建议优先使用 SMBus。

注意:

  • Functionality flag 是 Linux 的某个 I2C 控制器驱动所支持的功能。
  • 比如 Functionality flag: I2C_FUNC_SMBUS_QUICK,表示需要 I2C 控制器支持 SMBus Quick Command

符号的含义

在这里插入图片描述

SMBus Quick Command

在这里插入图片描述

只是用来发送一位数据:R/W#本意是用来表示读或写,但是在 SMBus 里可以用来表示其他含义。比如某些开关设备,可以根据这一位来决定是打开还是关闭。

Functionality flag: I2C_FUNC_SMBUS_QUICK

SMBus Receive Byte

在这里插入图片描述

I2C-tools 中的函数:i2c_smbus_read_byte()。读取一个字节,Host adapter 接收到一个字节后不需要发出回应信号(上图中 N 表示不回应)。

Functionality flag: I2C_FUNC_SMBUS_READ_BYTE

SMBus Send Byte

在这里插入图片描述

I2C-tools 中的函数:i2c_smbus_write_byte()。发送一个字节。

Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE

SMBus Read Byte

在这里插入图片描述
I2C-tools 中的函数:i2c_smbus_read_byte_data()。先发出 Command Code(它一般表示芯片内部的寄存器地址),再读取一个字节的数据。上面介绍的 SMBus Receive Byte 是不发送 Comand,直接读取数据。

Functionality flag: I2C_FUNC_SMBUS_READ_BYTE_DATA

SMBus Read Word

在这里插入图片描述
I2C-tools 中的函数:i2c_smbus_read_word_data()。先发出 Command Code(它一般表示芯片内部的寄存器地址),再读取 2 个字节的数据。

Functionality flag: I2C_FUNC_SMBUS_READ_WORD_DATA

SMBus Write Byte

在这里插入图片描述
I2C-tools 中 的 函 数 : i2c_smbus_write_byte_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的数据。

Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE_DATA

SMBus Write Word

在这里插入图片描述
I2C-tools 中 的 函 数 : i2c_smbus_write_word_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的数据。

Functionality flag: I2C_FUNC_SMBUS_WRITE_WORD_DATA

SMBus Block Read

在这里插入图片描述

I2C-tools 中 的 函 数 : i2c_smbus_read_block_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发起度操作:

  • 先读到一个字节(Block Count),表示后续要读的字节数
  • 然后读取全部数据
Functionality flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA

SMBus Block Write

在这里插入图片描述

I2C-tools 中 的 函 数 : i2c_smbus_write_block_data() 。 先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的 Byte Conut(表示后续要发出的数据字节数),最后发出全部数据。

Functionality flag: I2C_FUNC_SMBUS_WRITE_BLOCK_DATA

I2C Block Read

在一般的 I2C 协议中,也可以连续读出多个字节。它跟 SMBus Block Read 的差别在于设备发出的第 1 个数据不是长度 N,如下图所示:

在这里插入图片描述
I2C-tools 中的函数:i2c_smbus_read_i2c_block_data()。先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的 ByteConut(表示后续要发出的数据字节数),最后发出全部数据。

Functionality flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK

I2C Block Write

在一般的 I2C 协议中,也可以连续发出多个字节。它跟 SMBus BlockWrite 的差别在于发出的第 1 个数据不是长度 N,如下图所示

在这里插入图片描述

I2C-tools 中的函数:i2c_smbus_write_i2c_block_data()。先发出Command Code(它一般表示芯片内部的寄存器地址),再发出 1 个字节的 ByteConut(表示后续要发出的数据字节数),最后发出全部数据。

Functionality flag: I2C_FUNC_SMBUS_WRITE_I2C_BLOCK

SMBus Block Write - Block Read Process Call

在这里插入图片描述

先写一块数据,再读一块数据。

Functionality flag: I2C_FUNC_SMBUS_BLOCK_PROC_CALL

Packet Error Checking (PEC)

PEC 是一种错误校验码,如果使用 PEC,那么在 P 信号之前,数据发送方要发送一个字节的 PEC 码(它是 CRC-8 码)。以 SMBus Send Byte 为例,下图中,一个未使用 PEC,另一个使用 PEC:
在这里插入图片描述

I2C 系统的重要结构体

APP 通过 i2c_adapter 与 i2c_client 传输 i2c_msg

i2c_adapter

使用 i2c_adapter 结构体表示一个 I2C BUS,或称为 I2C Controller,里面有2 个重要的成员:

  • nr:第几个 I2C BUS(I2C Controller)
  • i2c_algorithm结构体,里面有该 I2C BUS 的传输函数,用来收发 I2C 数据

i2c_adapter 结构体原型:
在这里插入图片描述

i2c_algorithm 结构体原型:

在这里插入图片描述

i2c_client

使用 i2c_client 结构体来表示一个 I2C Device,里面有2 个重要的成员:

  • addr:表示设备地址
  • adapter:表示挂载在那个I2C控制器

在这里插入图片描述

i2c_msg

在上面的 i2c_algorithm 结构体中可以看到要传输的数据被称为:i2c_msg,里面有2 个重要的成员:

  • flags :用来表示传输方向:bit 0 等于 I2C_M_RD 表示读,bit 0 等于 0 表示写
  • addr:表示从设备的地址
  • len:表示读写的数据长度
  • buf:表示内容

i2c_msg 结构体原型:
在这里插入图片描述

内核传输数据

核心的传输函数 i2c_transfer
在这里插入图片描述

msgs是结构体数组,因为不止有一个msg

例如在读取指定设备的指定地址的数据时,需要发送2个msg,告诉从设备要访问的地址以及要执行读操作

在这里插入图片描述

I2C-Tools调试工具

下载地址:I2Ctools调试工具下载地址

该工具集包含以下命令:i2cdetect、i2cdump、i2cget、i2cset。

i2c-tools的重要意义就是开发人员既不需要编写复杂的Linux驱动、也不需要编写应用程序,只需要输入几个简单的命令就可以调试i2c设备,比如:设置i2c设备寄存器、获得i2c设备寄存器的值

I2C-Tools工具的使用

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

APP 访问硬件肯定是需要驱动程序的,对于 I2C 设备,内核提供了驱动程序 drivers/i2c/i2c-dev.c,编写应用后通过它可以直接使用下面的 I2C 控制器驱动程序来访问 I2C 设备。框架如下:
在这里插入图片描述
APP 通过 I2C Controller 与 I2C Device 传输数据
在这里插入图片描述

交叉编译 I2C-Tools

确保在Ubuntu设置交叉编译工具链,此时设置了环境变量:${CROSS_COMPILE}

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

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

改为(指定交叉编译工具链前缀, 去掉问号):
CC      = $(CROSS_COMPILE)gcc
AR      = $(CROSS_COMPILE)ar
STRIP   = $(CROSS_COMPILE)strip

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

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

想静态链接的话,执行:make USE_STATIC_LIB=1,此时就不需要将libi2c.so移植到开发板上

用法

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             IMX6ULL I2C(0x40013000)                 I2C adapter
i2c-2   i2c             IMX6ULL I2C(0x5c002000)                 I2C adapter
i2c-0   i2c             IMX6ULL 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

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  

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

-f表示:对于UU(已经挂载且有对应驱动)的设备,需要强制写入

i2cdump:查看i2c设备所有寄存器的值(和i2cget相同)

i2cdump -y -f 0 0x57

参数 意义

  • -y 取消交互过程,直接执行命令
  • -f 强制访问该设备
  • 0 表示i2c总线编号
  • 0x57 表示i2c设备地址
  • 从命令执行结果可知i2cdump命令获得的寄存器值和i2cget命令相同。

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 omitted)
  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 //如果设备地址不变,后面的设备地址可省略

底层原理

使用I2C-Tools时怎么指定I2C控制器?

设备节点与I2C控制器一一对应:

在这里插入图片描述
i2c-dev.c提供为每个I2C控制器(I2C Bus、I2C Adapter)都生成一个设备节点:/dev/i2c-0、/dev/i2c-1等等
open某个/dev/i2c-X节点,就是去访问该I2C控制器下的设备

使用I2C-Tools时怎么指定I2C设备?(需要知道地址值)

通过ioctl指定I2C设备的地址

ioctl(file, I2C_SLAVE, address)
  • 如果该设备已经有了对应的设备驱动程序,则返回失败
ioctl(file, I2C_SLAVE_FORCE, address)
  • 如果该设备已经有了对应的设备驱动程序
  • 但是还是想通过i2c-dev驱动来访问它(绕开驱动程序)
  • 则使用这个ioctl来指定I2C设备地址

使用I2C-Tools时怎么传输数据?

两种方式

  • 一般的I2C方式:ioctl(file, I2C_RDWR, &rdwr)
  • SMBus方式:ioctl(file, I2C_SMBUS, &args)

源码分析

使用I2C方式

示例代码:i2ctransfer.c
在这里插入图片描述

使用 SMBus 方式

示例代码:i2cget.c、i2cset.c
在这里插入图片描述

使用I2C-Tools操作传感器AP3216C

传感器AP3216C介绍

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

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

根据手册可知,AP3216C的设备地址是0x1E(通过i2cdetect -y -a x 检查是否在哪个总线上,地址为0x1e),假设节在I2C BUS0上

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

使用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

使用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

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

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

相关文章

11_Linux阻塞与非阻塞

目录 阻塞和非阻塞IO简介 等待队列 等待队列头 等待队列项 轮询 Linux驱动下的poll操作函数 阻塞式访问IO实验 阻塞式访问IO驱动程序编写 运行测试 非阻塞式IO实验 运行测试 阻塞和非阻塞IO简介 阻塞和非阻塞IO是Linux驱动开发里面很常见的两种设备访问模式,在编写…

充分利用测试自动化的 10 个最佳实践

目录 前言: 实践1:手动和自动测试结合 实践2:特别注意回归测试 实践3:包括端到端测试 实践4:为自动化测试提供集体所有权 实践5:详细计划与测试相关的所有流程 实践6:选择适合您需求的自…

Python随机生成2堆三维点云点,有固定的重复率并可视化

Python随机生成2堆三维点云点,有固定的重复率并可视化 1. 效果图2. 源码 这篇博客源于博友的提问,刚好电脑在旁边没啥事,那就开整吧。 np.random 生成随机点(提供了俩种方法,1. xyz限制都是0~MAX值,2. xyz分…

IDEA中使用.env文件配置信息

一、说明 我们以配置阿里云的 Access Key 的信息为例(配置别的信息当然也可以,我只是举个例子!!!),假设我们的代码中需要用到它。Access Key有两个属性,分别为【ALIBABA_CLOUD_ACCE…

【剧前爆米花--前端三剑客】html的一些常用标签及其实例

作者:困了电视剧 专栏:《JavaEE初阶》 文章分布:这是一篇关于html前端的文章,在这篇文章中我会简单介绍一些常用的html标签,并给出他们的应用实例,希望对你有所帮助! 目录 html常见标签 标题标…

python_day3_tuple

元组tuple :无法修改(只读的列表) t1 () t2 tuple() t3 (1, java, True, ()) print(f"t1的数据类型是:{type(t1)}") print(f"t2的数据类型是:{type(t2)}") print(f"t3的数据类型是&#…

ChatLaw:北大团队智能法律助手,国产大模型成功应用普惠法律服务

“ 技术发展的本质是普惠,用技术降低普通人获取法律知识的成本,向社会输出普惠的公平正义。—— 北京大学 ChatLaw 项目组” 刚刚清华团队升级了国产大模型:ChatGLM2-6B,ChatGLM2-6B 初体验。 转眼这两天北大团队推出的智能法律助…

DAY36:贪心算法(三)最大子数组和+买卖股票最佳时机

文章目录 53.最大子数组和枚举思路暴力解法贪心思路完整版时间复杂度 122.买卖股票的最佳时机Ⅱ(解法比较巧妙)思路完整版总结 53.最大子数组和 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元…

Java开发基础系列(一):Java设计概述

😊 作者: 一恍过去 💖 主页: https://blog.csdn.net/zhuocailing3390 🎊 社区: Java技术栈交流 🎉 主题: Java开发基础系列(一):Java设计概述 ⏱️ 创作时间: 2023年…

【漏洞复现】nginxWebUI 存在前台远程命令执行漏洞

文章目录 前言声明一、nginxWebUI 简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 nginxWebUI 存在前台远程命令执行漏洞,攻击者通过该漏洞获取服务器控制权限进而进一步获取敏感数据信息。 声明 请勿利用文章内的相关技术从事非法测试,由…

# 文盘Rust -- FFI 浅尝

作者: jiashiwen 原文来源: https://tidb.net/blog/cfa03c39 notice"Rust is a trademark of the Mozilla Foundation in the US and other countries." rust FFI 是rust与其他语言互调的桥梁,通过FFI rust 可以有效继承 C 语言…

道德与社会问题简报 #4: 文生图模型中的偏见

简而言之: 我们需要更好的方法来评估文生图模型中的偏见 介绍 文本到图像 (TTI) 生成 现在非常流行,成千上万的 TTI 模型被上传到 Hugging Face Hub。每种模态都可能受到不同来源的偏见影响,这就引出了一个问题: 我们如何发现这些模型中的偏见&#xff1…

Android启动流程优化 上篇

Android启动流程优化 上篇 本文链接:Android启动流程优化 上篇_猎羽的博客-CSDN博客 启动流程 各个阶段图 1、各个阶段的概括总结 分为5个大阶段或者10个小阶段 【字节跳动团队】内部论坛分享也是这么处理的 补充一些只是细节点: application#onCreate()运行…

基于多案例系统学习防洪评价报告编制方法与水流数学模型建模(HECRAS、MIKE、EFDC、Delft3D、FVCOM、SWAT、SWMM等模型应用)

目录 ​专题一 《防洪评价报告编制导则解读河道管理范围内建设项目编制导则》(SL/T808- 2021)解读编制导则解读 专题二 防洪评价相关制度与解析 ★专题三 案例演练解析 专题四 防洪评价地形获取及常用计算实践 专题五 HEC-RAS软件原理及应用案例解析…

leetcode160.相交链表

https://leetcode.cn/problems/intersection-of-two-linked-lists/solution/ 相交链表是指两个单向链表在某个节点处相交,之后形成了共同的后续部分。通常,两个链表的长度不相等。在相交节点之前,两个链表的节点数可能不同,但在相…

Java后端编译与优化

如果我们将字节码看作是程序语言的一种中间表示形式,那编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施相关的二进制机器码,它都可以视为整个编译过程的后端。 1 即时编译器 即时编译器是指运行时将热点代码编译成本地机器码&#xff…

程序员必须掌握哪些算法?——前端开发工程师需要掌握的算法

文章目录 📋前言🎯什么是算法?🎯前端开发工程师需要掌握的算法🧩排序算法(如快速排序、归并排序)🧩搜索算法(如二分搜索)🧩图算法(如广…

【Unity造轮子】2D横版平台跳跃游戏实现多段跳完美手感(含源码)

文章目录 前言先看效果,手感很丝滑原理开始1. 看到检测点的检测范围2. 二段跳实现3. 动画控制器配置 源码扩展完结 前言 随着游戏技术的不断发展,2D横版平台跳跃游戏成为许多玩家的最爱。这类游戏以其简单而有趣的玩法和精致的视觉效果吸引着无数游戏爱…

Kotlin~Decorator装饰器模式

概念 装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。可以运行时动态添加新的功能,而无需改变原来的代码。 特点: 灵活扩展新的功能动态…

接口设计的总结

目录 前言 设计好接口的 36 个锦囊 总结 前言 作为后端开发,不管是什么语言,Java、Go 还是 C,其背后的后端思想都是类似的。我们做后端开发工程师,主要工作就是:如何把一个接口设计好。所以,今天就给大家…