Linux i2c-tools 工具包使用指南

简介

i2c-tools是Linux系统下操作I2C总线的一套实用工具集,包含多种命令行工具,用于扫描、读取、写入I2C设备。本文档详细介绍各个工具的使用方法,适用于嵌入式开发、硬件调试和系统维护人员。

安装方法

Debian/Ubuntu系统

sudo apt update
sudo apt install i2c-tools

RHEL/CentOS系统

sudo yum install i2c-tools

源码编译安装

git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
cd i2c-tools
make
sudo make install

使用前准备

  1. 确保内核已加载I2C驱动:
sudo modprobe i2c-dev
  1. 确保用户有访问I2C设备的权限:
# 将当前用户添加到i2c组
sudo usermod -a -G i2c $USER
# 重新登录使权限生效
# 或临时修改设备权限
sudo chmod 666 /dev/i2c-*

主要工具介绍

1. i2cdetect - I2C总线扫描工具

功能
  • 列出系统中可用的I2C总线
  • 扫描I2C总线上的设备
基本用法
# 列出所有I2C总线
i2cdetect -l

# 扫描特定总线上的设备
i2cdetect -y 1

# 扫描特定地址范围的设备
i2cdetect -y -a 1

# 使用不同模式扫描
i2cdetect -y -r 1  # 使用SMBus读取模式
输出示例
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: 50 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                         
参数说明
参数 说明
-l 列出所有I2C适配器
-y 跳过交互式确认
-a 扫描所有地址(包括保留地址)
-r 使用SMBus读取命令进行扫描
-F 使用SMBus快速读取命令
-q 使用SMBus快速写入命令

2. i2cget - 读取I2C设备寄存器

功能

读取I2C设备特定寄存器的值

基本用法
# 从I2C总线1上地址为0x48的设备读取寄存器0x00的值
i2cget -y 1 0x48 0x00

# 读取字(word)数据(两个字节)
i2cget -y 1 0x48 0x00 w

# 以长整数格式读取(四个字节)
i2cget -y 1 0x48 0x00 i
参数说明
参数 说明
-y 跳过交互式确认
b 读取字节数据(默认)
w 读取字(word)数据
c 读取字节数据,不发送命令字节
i 读取长整数(long integer)数据

3. i2cset - 向I2C设备寄存器写入数据

功能

向I2C设备的寄存器写入数据

基本用法
# 向I2C总线1上地址为0x48的设备的寄存器0x01写入值0x55
i2cset -y 1 0x48 0x01 0x55

# 写入字(word)数据
i2cset -y 1 0x48 0x01 0x5555 w

# 写入数据并立即读回以验证
i2cset -y 1 0x48 0x01 0x55 b -r
参数说明
参数 说明
-y 跳过交互式确认
b 字节数据(默认)
w 字(word)数据
i 长整数(long integer)数据
-m mask 应用位掩码,只修改特定位
-r 写入后立即读回以验证

4. i2cdump - 读取I2C设备所有寄存器

功能

转储I2C设备的寄存器内容,显示所有可读取的寄存器值

基本用法
# 读取I2C总线1上地址为0x48的设备的所有寄存器(0x00-0xFF)
i2cdump -y 1 0x48

# 指定寄存器范围
i2cdump -y 1 0x48 b 0x00 0x1F

# 以字(word)格式读取寄存器
i2cdump -y 1 0x48 w
输出示例
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 19 80 02 55 74 00 1c 74 00 00 00 00 00 00 00 00    .??Ut?.t........
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
80: 19 80 02 55 74 00 1c 74 00 00 00 00 00 00 00 00    .??Ut?.t........
参数说明
参数 说明
-y 跳过交互式确认
b 字节格式读取(默认)
w 字(word)格式读取
i 长整数格式读取
c 字节格式读取,但不发送命令字节
-r FIRST-LAST 指定寄存器范围

5. i2ctransfer - 执行复杂的I2C传输

功能

执行一系列自定义的I2C传输操作,适合复杂的I2C协议通信

基本用法
# 写入两个字节后读取一个字节
i2ctransfer -y 1 w2@0x48 0x01 0x02 r1

# 多个操作组合
i2ctransfer -y 1 w1@0x48 0x00 r2 w1@0x48 0x01 r3
操作格式
  • w<字节数>@<地址> <数据1> <数据2>...: 写操作
  • r<字节数>: 读操作
参数说明
参数 说明
-y 跳过交互式确认
-f 强制执行,忽略传输限制
-v 详细模式,显示传输细节

实用案例

1. 监控温度传感器

以LM75温度传感器为例(地址0x48):

# 读取温度寄存器(0x00)
value=$(i2cget -y 1 0x48 0x00 w)
# 转换为摄氏度(LM75特定算法)
temp=$(echo "scale=2; $((0x$value)) / 256" | bc)
echo "当前温度: ${temp}°C"

2. 配置EEPROM

以AT24C32 EEPROM为例(地址0x50):

# 写入数据到EEPROM
i2cset -y 1 0x50 0x00 0x01 0x02 0x03 0x04 i

# 读取EEPROM数据
i2cdump -y 1 0x50 b 0x00 0x0F

3. 控制GPIO扩展器

以PCF8574 GPIO扩展器为例(地址0x20):

# 读取当前IO状态
current=$(i2cget -y 1 0x20)
echo "当前IO状态: 0x$current"

# 设置特定IO为高电平(例如PIN3)
mask=$((1 << 3))
new_value=$((0x$current | $mask))
i2cset -y 1 0x20 $new_value

4. 探测I2C多路复用器通道

以PCA9548多路复用器为例(地址0x70):

# 选择通道0
i2cset -y 1 0x70 0x01

# 探测通道0上的设备
i2cdetect -y 2  # 假设通道0映射为i2c-2

# 切换到通道1
i2cset -y 1 0x70 0x02

# 探测通道1上的设备
i2cdetect -y 3  # 假设通道1映射为i2c-3

常见问题排查

1. “Error: Could not open file ‘/dev/i2c-X’ or ‘/dev/i2c/X’: No such file or directory”

解决方法:

  • 确认内核已加载I2C驱动:sudo modprobe i2c-dev
  • 验证设备文件存在:ls -l /dev/i2c*
  • 检查总线编号是否正确

2. “Error: Can’t use SMBus Quick Write command on this adapter”

解决方法:

  • 尝试其他扫描模式:i2cdetect -y -r 1
  • 驱动可能不支持某些SMBus功能

3. “Error: Write failed: Remote I/O error”

解决方法:

  • 检查设备地址是否正确
  • 验证设备是否正常连接
  • 确认设备的寄存器映射

4. 没有权限访问I2C设备

解决方法:

# 临时解决
sudo chmod 666 /dev/i2c-*

# 永久解决
sudo groupadd -f i2c
sudo usermod -a -G i2c $USER
echo 'KERNEL=="i2c-[0-9]*", GROUP="i2c", MODE="0660"' | sudo tee /etc/udev/rules.d/10-i2c.rules
sudo udevadm control --reload-rules
sudo udevadm trigger

进阶使用技巧

1. 使用shell脚本自动化I2C操作

#!/bin/bash
# 示例:每10秒读取一次温度传感器
while true; do
  temp=$(i2cget -y 1 0x48 0x00)
  echo "$(date): 温度读数 0x$temp"
  sleep 10
done

2. 使用Python结合smbus2库

#!/usr/bin/env python3
import smbus2
import time

bus = smbus2.SMBus(1)  # 使用I2C总线1

# 读取温度传感器
temp_raw = bus.read_byte_data(0x48, 0x00)
print(f"当前温度: {temp_raw} (原始值)")

# 写入数据到设备
bus.write_byte_data(0x20, 0x00, 0xFF)  # 写入0xFF到寄存器0x00

3. 创建别名简化常用命令

# 添加到~/.bashrc或~/.bash_aliases
alias i2cscan='i2cdetect -y 1'
alias i2ctemp='i2cget -y 1 0x48 0x00'
alias i2cgpio='i2cget -y 1 0x20'

参考资源

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐