PCA9548 是一种 I2C 总线多路复用器/扩展器,主要解决以下实际需求:
1.扩展 I2C 总线数量
一个 I2C 主控制器通常只能挂载有限数量的从设备(受限于地址冲突和总线电容)。PCA9548 可将 1 路上行 I2C 扩展为 8 路下行通道,每个通道可独立挂载多个设备,从而大幅增加系统可连接的 I2C 设备数量。

2.避免地址冲突
当多个相同型号的 I2C 设备(如多个温度传感器、ADC 等)使用相同从地址时,无法直接挂在同一总线上。通过 PCA9548 的不同通道隔离,每个通道上的设备地址可以相同,互不干扰。

3.支持不同电压电平的总线通信
PCA9548 的 VDD 引脚可限制通门电压,允许上行总线与下行各通道使用不同的工作电压(如 1.8V、2.5V、3.3V、5V)。这使得不同电压域的 I2C 器件可以直接通信,无需额外电平转换电路。

4.提高系统可靠性
通过硬件复位引脚(RESET)可将 PCA9548 恢复至默认断开状态,切断所有下行通道,便于故障恢复或系统初始化。
每个通道独立控制,可隔离故障设备,避免单个设备故障影响整个总线。
简化 PCB 布局与信号完整性
将多个设备分散到不同通道,可降低单条总线的电容负载,改善信号质量,尤其适用于长距离或高噪声环境。

典型应用场景:
服务器主板(监控多个温度/电压传感器)
多传感器数据采集系统
多摄像头/显示器 EDID 通道切换
工业控制中多模块 I2C 总线管理
总之,PCA9548 的核心价值在于以低成本、小封装解决 I2C 总线地址冲突、电平兼容和扩展性问题,是复杂 I2C 系统设计中不可或缺的组件。

在 Linux 下使用 i2c-tools 工具可以访问 PCA9548 多路复用器的多个通道,核心思路是:先向 PCA9548 的控制寄存器写入通道选择值,然后对该通道下的下游设备进行读写。下面分步骤说明。
在这里插入图片描述
PCA9548 的控制寄存器是一个 8 位寄存器,每一位对应一个通道(bit0=通道0,bit1=通道1,…,bit7=通道7)。写入 0x01 表示选中通道0,写入 0x02 表示选中通道1,写入 0x03 表示同时选中通道0和1(允许地址不冲突时)。

使用 i2cset 命令写入控制字节:

bash

1.切换到通道0(假设PCA9548地址为0x70,总线为1)

i2cset -y 1 0x74 0x01

  • y:自动确认(跳过交互提示)。
  • 1:总线编号。
  • 0x74:PCA9548 的 I2C 地址(可通过电阻配置成70|71|72|73|74|75|76|77)。
  • 0x01:要写入的值(选择通道0)。
    切换到其他通道只需改变最后一个值,例如:
  • 通道1:i2cset -y 1 0x74 0x02
  • 通道7:i2cset -y 1 0x74 0x80
  • 同时选择通道0和1:i2cset -y 1 0x74 0x03

2. PCA9548 的地址可能显示为 UU(被内核驱动占用i2c-mux-pca954x.c)

  • 现象:i2cdetect -y 1 输出中,PCA9548 的地址(常见 0x70~0x77)显示为 UU,而不是数字或 --
  • 原因:系统已加载 pca954x 内核驱动,并自动接管了 PCA9548。驱动在初始化时可能默认打开了通道0(或根据设备树配置打开了特定通道),因此下游设备出现在物理总线上,而 PCA9548 本身不再响应普通用户态扫描(驱动占用)。
  • UU = 该地址已被内核驱动占用(kernel driver bound),说明 i2c-mux-pca954x 驱动已自动加载并接管了 PCA9548,内核驱动工作正常。优先使用虚拟子总线方案,只有在必须手动控制寄存器时才考虑解绑驱动。
  • 解除驱动绑定(1-0074 = i2c总线1上地址0x74)echo "1-0074" | sudo tee /sys/bus/i2c/drivers/pca954x/unbind

3. 为什么能看到下游设备?

  • 情况A:驱动已加载并打开了通道0 → 下游设备自然可见。
  • 情况B:PCA9548 处于复位状态(RESET 低电平)时,所有通道默认关闭,下游设备不应可见。如果仍然可见,可能是下游设备直接连接到了主总线(PCB 设计错误),或者 PCA9548 被旁路(某些模块可能带有直通模式,但标准 PCA9548 无此功能)。
  • 情况C:之前手动通过 i2cset 切换过通道,且未关闭,导致通道保持开启。重启系统或复位 PCA9548 可恢复默认状态。

4.注意事项

  • 不要混淆 UU 与数字地址:UU 表示设备已被内核驱动使用,并非“未检测到”。这是正常现象,说明驱动已正确识别 PCA9548。
  • 驱动自动管理时,不要手动使用 i2cset 切换通道:手动操作可能与驱动状态冲突,导致不可预期行为。
  • 检查设备树配置:如果系统使用设备树,确保 pca954x 节点配置正确(如 i2c-mux-idle-disconnect 属性),避免通道间干扰。

5、驱动已自动管理通道切换,直接用虚拟子总线编号操作即可,无需手动切换:

# 查找各通道对应的虚拟总线号
i2cdetect -l
# i2c-1   主总线(PCA9548 在此,显示UU)
# i2c-4   i2c-mux-pca954x ch0  ← 通道0
# i2c-5   i2c-mux-pca954x ch1  ← 通道1
# i2c-6   i2c-mux-pca954x ch2  ← 通道2
# ...

# 直接扫描通道0的设备(内核自动切换复用器)
i2cdetect -y 4    # 通道0

# 读取通道0下地址0x48设备的寄存器0x00
i2cget -y 4 0x48 0x00

# 读取通道2下地址0x40设备
i2cget -y 6 0x40 0x00
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐