在 Linux 开发中,i2c-tools 是一套非常强大的用户空间工具集,用于调试 I2C 总线和设备。它直接基于 i2c-dev 驱动运行。
1. 安装
在 Debian/Ubuntu 系统上:
bash
sudo apt-get install i2c-tools1
在 Buildroot/Yocto 构建的嵌入式系统中,通常需要在 make menuconfig 中选中 Target packages -> Hardware handling -> i2c-tools。
2. 常用命令
2.1 i2cdetect - 扫描总线
用于检测 I2C 总线上挂载的设备。
bash
# 列出所有安装的 I2C 总线
i2cdetect -l
# 扫描总线 1 上的设备 (-y 代表 yes,不询问确认)
i2cdetect -y 11
2
3
4
5
2
3
4
5
输出示例:
plaintext
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
--: 表示该地址没有设备响应 (NACK)。50: 表示地址0x50有设备响应 (ACK)。UU: 表示该地址的设备已经被内核驱动接管(Busy),用户空间可能无法访问。
2.2 i2cdump - 导出寄存器
用于导出设备的所有寄存器值。
bash
# 导出总线 1 上地址 0x50 设备的所有寄存器
i2cdump -y 1 0x501
2
2
2.3 i2cget - 读取寄存器
读取单个寄存器的值。
bash
# 读取总线 1,设备 0x50,寄存器 0x10 的值
i2cget -y 1 0x50 0x101
2
2
2.4 i2cset - 写入寄存器
写入单个寄存器的值。小心使用,写入错误可能导致设备异常!
bash
# 向总线 1,设备 0x50,寄存器 0x10 写入值 0xAB
i2cset -y 1 0x50 0x10 0xAB1
2
2
2.5 i2ctransfer - 发送自定义消息
这是较新的工具,支持更复杂的 I2C 消息序列(如多字节读写、重复开始条件等)。
bash
# 向设备 0x50 写 0x00,然后读 3 个字节 (通常用于读寄存器 0x00 开始的 3 个字节)
i2ctransfer -y 1 w1@0x50 0x00 r31
2
2
3. 调试技巧
3.1 无法检测到设备
- 检查接线: SDA/SCL 是否接反?GND 是否共地?
- 检查电压: 设备供电是否正常?
- 检查上拉: 是否有合适的上拉电阻?
- 检查地址: 某些设备有地址选择引脚,确认实际地址。
3.2 显示 UU
表示内核中已经有驱动加载并占用了该设备。
- 如果你想在用户空间操作它,需要先卸载对应的内核驱动 (
rmmod),或者在设备树中将其状态改为disabled。 - 或者使用
I2C_SLAVE_FORCE(编程时) 强制访问。
3.3 频率调整
如果信号质量差,可以尝试降低 I2C 频率。在设备树中修改 clock-frequency 属性,例如从 400000 改为 100000。