I2C 实战

本篇目标:理解 I2C(全志叫 TWI),并用 i2c-tools 扫描板子上挂的设备、读取寄存器。板子出厂在 twi2 上挂了 RTC、触摸屏、音频三颗芯片,正好拿来练手。
出厂固件已内置 i2c-tools。


什么是 I2C / TWI

I2C 是一种两线制低速总线(一根时钟 SCL、一根数据 SDA),用来让主控和板上的各种小芯片(传感器、RTC、触摸屏、音频Codec、EEPROM…)通信。每个从设备有一个 7 位地址,主控按地址找它读写。

全志平台习惯把 I2C 控制器叫做 TWI。本板设备树里只使能了 twi2(时钟 100kHz)——旧资料写的”TWI0/TWI5 用户扩展”与设备树不符,以本 SDK 为准,实际可用的是 twi2。


板子 twi2 上挂了哪些设备

出厂设备树在 twi2 节点下挂了三颗从设备:

从设备 I2C 地址 功能 设备树 compatible
PCF8563 0x51 RTC 实时时钟 nxp,pcf8563
GT9XX 0x5d 触摸屏 控制器 goodix,gt9xx
ES8388 0x11 音频 编解码 everest,es8323

也就是说,插上 RTC 电池、接上触摸屏、接上音频,这三颗芯片都已经在 twi2 总线上被系统识别并加载了驱动。


第一步:确认总线存在

在 Linux 里,twi2 通常对应 i2c-2(编号从 0 起)。先列出所有 I2C 总线:

root@YPT153EVB:~# i2cdetect -l
i2c-0   i2c       sunxi-i2c-v100-adapter     I2C adapter
i2c-1   i2c       sunxi-i2c-v100-adapter     I2C adapter
i2c-2   i2c       sunxi-i2c-v100-adapter     I2C adapter   <-- 这就是 twi2
...

i2c-2 即 twi2。


第二步:扫描 twi2 上的设备地址

root@YPT153EVB:~# i2cdetect -y 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 11 --     <-- ES8388 @0x11
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- --   <-- PCF8563 @0x51
60: -- -- -- -- -- -- -- -- -- -- -- -- -- 5d -- --   <-- GT9XX @0x5d
70: -- -- -- -- -- -- -- --

看到 11、51、5d 三个地址被占,正好对应上面三颗芯片,说明总线和设备都正常。

如果某些地址没出现:该芯片可能没焊/没接好/未上电;或设备树没加载对应节点。


第三步:读取一个设备的寄存器

以 PCF8563 RTC(@0x51) 为例,读它的”秒”寄存器(地址 0x02):

root@YPT153EVB:~# i2cget -y 2 0x51 0x02
0x58

返回值是 BCD 编码的秒(这里是 0x58 = 88?仅示例,实际请结合数据手册解读)。这只是演示”能读到”。

更省事的是直接用内核的 RTC 子系统(见《RTC 实战》篇):

root@YPT153EVB:~# hwclock -r        # 读取 RTC 时间

第四步:dump 一颗芯片看全貌

root@YPT153EVB:~# i2cdump -y 2 0x5d     # dump 触摸屏 GT9XX 的所有寄存器

适合排查”设备是不是这个值、配置对不对”。


怎么新增一个 I2C 设备(进阶)

如果你自己焊了一个 I2C 传感器(地址比如 0x48),要在板子上用,需要:

  1. 在设备树 twi2 节点下加一个子节点:
    &twi2 {
        status = "okay";
        my_sensor: my_sensor@48 {
            compatible = "vendor,my-sensor";
            reg = <0x48>;
        };
    };
  2. 提供对应内核驱动(或写成用户态用 i2c-dev 直接读)。
  3. 重新编译内核并烧录。

启用其它 TWI(如 twi0/twi5)同理:在 board-base.dtsi 把对应 &twiX 改为 status = "okay" 并配置 pinctrl 引脚,再重编。


排障

现象 处理
i2cdetect -l 没有 i2c-2 twi2 未使能;确认设备树 &twi2 status=okay
扫描不到某地址 芯片未上电/未焊接/地址错;检查硬件与 reg
读出来全是 0xff 设备没应答/总线拉不动;检查上拉电阻(I2C 必须上拉)
乱码/校验错 速率过高;twi2 默认 100kHz,高速设备另配

附:真实设备树片段(twi2 上挂的三颗芯片)

来自 BoardConfig/BoardType/ypt153evb-board.dts 的 &twi2 节点:

&twi2 {
    clock-frequency = <100000>;
    status = "okay";
    pcf8563: rtc@51 {
        status = "okay";
        compatible = "nxp,pcf8563";
        reg = <0x51>;
    };
    gt9xx: gt9xx@5d {
        compatible = "goodix,gt9xx";
        reg = <0x5d>;
        status = "okay";
        irq-gpios  = <&pio PA 22 GPIO_ACTIVE_LOW>;
        reset-gpios = <&pio PA 21 GPIO_ACTIVE_LOW>;
        touchscreen-size-x = <1024>;
        touchscreen-size-y = <600>;
    };
    es8388: es8388@11 {
        status = "okay";
        compatible = "everest,es8323";   // 驱动兼容 ES8388
        reg = <0x11>;
    };
};

这就是第 10/11/12 篇(音频 / RTC / 触摸屏)硬件上挂载位置的依据。

作者:Mai  创建时间:2026-10-20 16:48
最后编辑:陈柏林  更新时间:2026-11-05 14:56