PCA9574 I2C GPIO扩展器:双电源电平转换与实战应用详解 1. 项目概述与核心价值在嵌入式开发中我们常常会遇到一个经典难题主控芯片的GPIO通用输入输出引脚不够用了。无论是连接一排LED指示灯、读取多个按键状态还是驱动一组继电器当项目复杂度上升有限的GPIO资源很快就会捉襟见肘。这时候I2C GPIO扩展器就成了硬件工程师和嵌入式软件工程师的“救星”。它就像给你的主控芯片增加了一个“外挂”的I/O端口通过简单的I2C总线用两根线就能控制8个、16个甚至更多的GPIO极大地释放了主控的资源也让PCB布局布线变得清爽许多。然而仅仅扩展GPIO数量还不够。在今天的混合电压系统中比如一个由1.8V核心供电的微控制器去控制一个3.3V的传感器或者在一个由电池供电、电压会波动的设备中直接的电平连接可能导致通信失败甚至器件损坏。因此一个集成了电平转换功能的GPIO扩展器其价值就不仅仅是“数量扩展”更是“系统桥梁”。NXP的PCA9574正是这样一款将“数量扩展”与“电压桥接”两大功能合二为一的器件。它不仅仅是一个简单的8位I/O扩展芯片更是一个内置了电压转换能力的智能接口。其核心逻辑部分VDD可以工作在低至1.1V的电压下而I/O端口VDD(IO)则可以独立工作在1.1V至3.6V的宽电压范围内。这意味着你可以用一颗1.8V的MCU通过PCA9574去安全、可靠地读写或驱动一组3.3V的外设无需额外增加电平转换芯片简化了设计节省了成本和板面空间。除了核心的扩展与电平转换功能PCA9574还提供了许多贴心的“增值服务”可编程的内部上拉/下拉电阻100kΩ、总线保持Bus-Hold功能、可屏蔽的中断输出INT、硬件复位RESET引脚以及一个可以同时配置多个器件的“GPIO All Call”地址。这些特性让它特别适合应用在对功耗敏感静态电流1μA、对可靠性要求高如需要防抖动、防浮空的场合例如智能手机、便携式媒体播放器、工业PLC、服务器主板或者任何电池供电的物联网节点。接下来我将从一个实际使用者的角度深入拆解PCA9574的设计思路、寄存器配置逻辑、实际驱动方法并分享在项目中应用它时积累的一些实战经验和避坑指南。2. 核心特性与设计思路深度解析2.1 双电源轨与电平转换机制PCA9574最核心的竞争力在于其双独立电源轨设计VDD核心逻辑电源和VDD(IO)I/O端口电源。这是实现无缝电平转换的硬件基础。工作原理芯片内部的数字逻辑、I2C接口控制器、寄存器组等都由VDD供电1.1V - 3.6V。而实际的8个GPIO引脚P0-P7的电平高低则由VDD(IO)1.1V - 3.6V决定。芯片内部集成了电平转换电路负责在VDD域和VDD(IO)域之间进行信号翻译。设计考量灵活性VDD和VDD(IO)可以接相同电压如都是3.3V此时它就是一个标准的GPIO扩展器。也可以接不同电压例如VDD1.8V匹配MCUVDD(IO)3.3V匹配外围传感器此时它就承担了电平转换器的角色。隔离与保护这种设计在电气上提供了一定程度的隔离。即使I/O端口连接的某个外设发生故障导致VDD(IO)异常只要不超出绝对最大额定值核心逻辑和I2C总线通常不会受到影响提高了系统鲁棒性。功耗优化在电池供电场景MCU核心可能工作在1.2V以降低功耗而一些外围器件仍需3.3V。使用PCA9574可以避免为整个系统统一高压仅在需要的地方提供高压有助于整体功耗管理。实操心得务必确保VDD(IO)的电压不高于VDD电压加上0.5V具体需查手册。虽然芯片允许VDD(IO)独立设置但一般建议VDD(IO) VDD这样I/O输出高电平才能达到VDD(IO)保证驱动能力。如果VDD(IO)比VDD低太多内部电平转换电路可能无法正确识别来自VDD域的高电平信号。2.2 可配置的I/O结构与内部上拉/下拉PCA9574的每个GPIO都可以独立配置为输入或输出这是基本操作。但其内部集成的**可编程上拉/下拉电阻100kΩ和总线保持Bus-Hold**功能才是解决实际工程问题的利器。内部上拉/下拉Pull-Up/Pull-Down作用当GPIO配置为输入且外部没有主动驱动如按键未按下、传感器输出高阻态时一个确定的电阻上拉或下拉可以为引脚提供一个稳定的逻辑电平防止其悬空floating产生随机噪声和额外功耗。配置逻辑这个功能需要通过寄存器BKEN地址02h和PUPD地址03h配合使用。首先需要关闭总线保持功能BKEN寄存器bit00然后使能上拉/下拉功能BKEN寄存器bit11最后在PUPD寄存器中为每个引脚选择是上拉bit1还是下拉bit0。总线保持Bus-Hold作用这是一个比简单电阻更“智能”的功能。当使能后BKEN寄存器bit01如果GPIO引脚被外部驱动到某个电平高或低在外部驱动移除后内部电路会“记住”并保持这个电平直到被新的驱动改变。它不需要持续电流来维持电平功耗更低。适用场景非常适合连接那些输出阻抗高、驱动能力弱的器件或者用于在省电模式MCU GPIO设为高阻态下保持总线状态防止误触发。配置对比表功能选择BKEN寄存器 Bit0BKEN寄存器 Bit1PUPD寄存器引脚状态无外部驱动时总线保持1X (忽略)X (无效)保持最后一次被驱动的逻辑电平内部上拉01对应位1被弱上拉到VDD(IO)内部下拉01对应位0被弱下拉到GND高阻态禁用00X (无效)悬空电平不确定注意事项总线保持和内部上拉/下拉功能是互斥的不能同时使能。芯片上电或复位后默认两者都禁用BKEN0x00所有I/O引脚处于高阻输入状态。这是为了防止未知的外部电路与内部电阻冲突。因此初始化配置顺序至关重要必须先通过CFG寄存器设定好引脚方向再根据需要配置BKEN和PUPD。2.3 中断与复位系统中断INT引脚 这是一个开漏输出引脚低电平有效。当任何一个被配置为输入的GPIO引脚状态发生变化从高到低或从低到高并且该引脚的中断未被屏蔽时INT引脚就会被拉低向主控制器发出中断请求。屏蔽寄存器MSK每个输入引脚都可以独立屏蔽中断。上电默认所有中断被屏蔽MSK0xFF这是为了防止上电过程中引脚电平不稳定产生大量伪中断。状态寄存器INTS这是一个只读寄存器。当发生中断时读取此寄存器可以知道具体是哪个或哪些输入引脚的状态变化触发了中断。清除中断的条件是读取IN输入端口寄存器。只要读取了IN寄存器无论是否读取了INTS寄存器INT引脚都会恢复高电平。防误触设计将引脚从输出模式切换到输入模式时如果此时引脚的实际电平与IN寄存器中缓存的值不同会立即产生一个中断。因此最佳实践是在切换引脚方向前先读取一次IN寄存器以同步状态或者先屏蔽该引脚的中断。复位RESET系统 PCA9574提供三种复位方式上电复位POR当VDD电压从0V上升到超过VPOR阈值时自动发生。硬件复位将RESET引脚拉低并保持至少tw(rst)时间详见数据手册通常为几百纳秒。软件复位通过I2C总线向“通用呼叫地址00h”发送特定数据字节06h来实现。这对于通过程序远程复位多个扩展器非常有用。所有复位操作都会将芯片内部所有寄存器恢复为默认值所有GPIO设为输入、中断屏蔽、输出寄存器清零、极性不反转、总线保持/上拉下拉禁用。3. 寄存器详解与驱动程序设计理解并熟练操作PCA9574的8个寄存器是将其用好的关键。下面我们抛开数据手册的平铺直叙从软件驱动开发的角度重新梳理这些寄存器。3.1 寄存器地图与访问流程PCA9574有8个8位寄存器通过一个3位的指针在命令字节中来寻址。访问任何寄存器前都必须先发送一个命令字节Command Byte其最低3位D2-D0指定要访问的寄存器地址。命令字节格式Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 AI | X | X | X | X | D2 | D1 | D0AI(Auto-Increment)自动递增标志。如果设置为1则在每次读写数据字节后寄存器指针会自动加1方便连续访问多个寄存器。D2-D0寄存器地址。000对应输入寄存器001对应极性反转寄存器以此类推。完整的I2C访问流程起始条件START。发送设备地址 写位0。PCA9574的固定地址高7位是0100 000加上A0引脚决定的最低位构成8位地址。例如A0接地地址为0x40写或0x41读。发送命令字节指定要操作的寄存器。如果是写操作发送要写入该寄存器的数据字节。如果AI1可以连续发送多个数据字节寄存器地址会自动递增。如果是读操作发送一个重复起始条件Repeated START。再次发送设备地址但这次是读位1。从芯片读取数据字节。如果AI1可以连续读取多个寄存器的数据。停止条件STOP。3.2 关键寄存器功能解析与C语言示例假设我们使用一个STM32 MCUI2C外设已初始化并定义了基本的I2C_Write和I2C_Read函数。我们以A0接地的PCA9574为例写地址0x40读地址0x41。1. 初始化配置将P0-P3设为输出低电平P4-P7设为输入启用内部上拉#define PCA9574_ADDR_W 0x40 #define PCA9574_ADDR_R 0x41 // 寄存器地址定义 (D2-D0 bits) #define REG_INPUT 0x00 #define REG_POLARITY 0x01 #define REG_BKEN 0x02 #define REG_PUPD 0x03 #define REG_CONFIG 0x04 #define REG_OUTPUT 0x05 #define REG_MASK 0x06 #define REG_STATUS 0x07 void PCA9574_Init(void) { uint8_t cmd_data[2]; // 1. 配置引脚方向: P0-P3输出(0), P4-P7输入(1) // CFG寄存器: 位1表示输入位0表示输出 // 目标值: 0b11110000 0xF0 cmd_data[0] (0 7) | REG_CONFIG; // AI0, 地址04h cmd_data[1] 0xF0; I2C_Write(PCA9574_ADDR_W, cmd_data, 2); // 2. 设置输出寄存器的初始值: P0-P3输出低电平 // OUT寄存器: 只对输出引脚有效 cmd_data[0] (0 7) | REG_OUTPUT; // 地址05h cmd_data[1] 0x00; // P0-P3输出低 I2C_Write(PCA9574_ADDR_W, cmd_data, 2); // 3. 禁用总线保持使能内部上拉/下拉功能 // BKEN寄存器: bit00 (禁用Bus-Hold), bit11 (使能PU/PD) cmd_data[0] (0 7) | REG_BKEN; // 地址02h cmd_data[1] 0x02; // 0b00000010 I2C_Write(PCA9574_ADDR_W, cmd_data, 2); // 4. 为P4-P7输入引脚配置内部上拉电阻 // PUPD寄存器: 位1上拉位0下拉。我们为所有输入引脚上拉。 // 注意输出引脚(P0-P3)的配置在此寄存器中无效但为了一致性可以都设为1。 cmd_data[0] (0 7) | REG_PUPD; // 地址03h cmd_data[1] 0xFF; // 所有引脚内部上拉 I2C_Write(PCA9574_ADDR_W, cmd_data, 2); // 5. 配置中断屏蔽P4-P7使能中断P0-P3输出屏蔽中断 // MSK寄存器: 位1屏蔽位0使能 cmd_data[0] (0 7) | REG_MASK; // 地址06h cmd_data[1] 0x0F; // 0b00001111, P0-P3屏蔽P4-P7使能 I2C_Write(PCA9574_ADDR_W, cmd_data, 2); // 6. (可选) 读取一次输入寄存器以清除可能存在的伪中断状态 uint8_t dummy_read; PCA9574_ReadInputPort(dummy_read); }2. 读取输入端口状态并清除中断uint8_t PCA9574_ReadInputPort(uint8_t *data) { uint8_t cmd; uint8_t rx_data; // 发送命令字节指向输入寄存器(00h) cmd (0 7) | REG_INPUT; if (I2C_Write(PCA9574_ADDR_W, cmd, 1) ! HAL_OK) { return 0; // 写入命令失败 } // 重复起始切换为读模式读取数据 if (I2C_Read(PCA9574_ADDR_R, rx_data, 1) ! HAL_OK) { return 0; // 读取数据失败 } *data rx_data; return 1; // 成功 // 注意此操作会自动清除INT引脚的中断状态 }3. 控制输出引脚void PCA9574_SetOutput(uint8_t pin_mask, uint8_t value) { // pin_mask: 要控制的引脚位掩码例如 (10) 表示P0 // value: 0置低非0置高通常用1 uint8_t cmd_data[2]; uint8_t current_output; // 先读取当前的输出寄存器状态 cmd_data[0] (0 7) | REG_OUTPUT; I2C_Write(PCA9574_ADDR_W, cmd_data, 1); I2C_Read(PCA9574_ADDR_R, current_output, 1); // 根据value更新指定位 if (value) { current_output | pin_mask; // 置高 } else { current_output ~pin_mask; // 置低 } // 写回新的输出值 cmd_data[0] (0 7) | REG_OUTPUT; cmd_data[1] current_output; I2C_Write(PCA9574_ADDR_W, cmd_data, 2); }3.3 “GPIO All Call”功能的应用这是一个非常实用的功能允许你同时向总线上多个具有不同地址的PCA9574发送相同的配置命令。它通过一个特殊的“全体呼叫”地址0x00写模式来实现。使用场景系统中有3个PCA9574地址分别为0x40, 0x42, 0x44你需要在上电时将它们所有的GPIO都初始化为输入并启用上拉。常规做法需要分别向0x40, 0x42, 0x44各发送一套配置指令共3次I2C传输。使用All Call的做法向地址0x00全体呼叫地址发送写请求。发送命令字节和数据字节例如配置CFG寄存器为0xFF。总线上所有能识别全体呼叫地址的PCA9574都会执行这条写命令。代码示例void PCA9574_AllCall_InitAsInputWithPullUp(void) { uint8_t cmd_data[2]; uint8_t all_call_addr 0x00; // GPIO All Call 地址 // 1. 配置所有引脚为输入 cmd_data[0] (0 7) | REG_CONFIG; // AI0, 地址04h cmd_data[1] 0xFF; // 所有位为1即全部设为输入 I2C_Write(all_call_addr, cmd_data, 2); // 2. 使能内部上拉/下拉功能 cmd_data[0] (0 7) | REG_BKEN; cmd_data[1] 0x02; // 禁用Bus-Hold使能PU/PD I2C_Write(all_call_addr, cmd_data, 2); // 3. 设置为上拉模式 cmd_data[0] (0 7) | REG_PUPD; cmd_data[1] 0xFF; // 全部上拉 I2C_Write(all_call_addr, cmd_data, 2); }重要提示GPIO All Call功能只能用于写操作不能用于读操作。因为读操作需要从设备返回数据多个设备同时返回会导致总线冲突。4. 硬件设计要点与PCB布局建议4.1 电源与去耦设计PCA9574的双电源设计带来了灵活性也增加了布板的复杂性。VDD和VDD(IO)的连接如果不需要电平转换最简单的方法是将VDD和VDD(IO)短接并连接到系统的数字电源如3.3V。如果需要电平转换则分别连接到对应的电源域。务必确保两个电源域的地VSS是共地的。去耦电容每个电源引脚VDD和VDD(IO)到地VSS都必须放置一个100nF的陶瓷电容并且尽可能靠近芯片引脚放置距离最好在2mm以内。这是为了滤除电源线上的高频噪声为芯片内部开关电路提供瞬态电流保证其稳定工作。对于VDD(IO)如果其负载较重例如驱动多个LED可以考虑再并联一个10μF的钽电容或电解电容以提供更大的储能。VSS引脚与散热焊盘对于HVQFN16封装芯片底部有一个裸露的散热焊盘。这个焊盘在内部是连接到VSS的。在PCB设计时必须将这个焊盘通过过孔良好地连接到地层。这不仅是为了散热更是为了提供稳定的电气接地。建议在焊盘下方打一个阵列的过孔例如3x3并确保与地平面有良好的连接。4.2 I2C总线布线PCA9574的I2C接口支持标准模式100kHz和快速模式400kHz。为了确保通信可靠布线时需注意上拉电阻SDA和SCL线是开漏输出必须通过上拉电阻连接到VDD注意是VDD不是VDD(IO)。电阻值的选择取决于总线电容和通信速度。对于400kHz和标准负载200pF4.7kΩ是一个常用值。如果总线较长、设备较多导致电容较大可以减小电阻值如2.2kΩ以加快上升沿如果对功耗敏感可以增大电阻值如10kΩ。走线SDA和SCL应尽可能保持等长、平行走线并远离高频噪声源如开关电源、时钟线。在复杂的板子上可以考虑将它们走在内层用地平面进行屏蔽。4.3 GPIO引脚的保护与驱动ESD保护PCA9574的I/O引脚内部已有ESD保护二极管但对于连接外部接口如按键、连接到机壳的LED的引脚建议在端口入口处增加额外的TVS管或稳压二极管以抵御更强的静电或浪涌冲击。驱动能力PCA9574的GPIO输出为推挽结构典型驱动能力为源电流1mA灌电流3mA。这意味着它可以直接驱动LED需串联限流电阻但亮度可能不高。它可以驱动光耦、小功率继电器线圈需加续流二极管或作为其他逻辑器件的输入。它不能直接驱动电机、电磁阀等大电流负载。驱动此类负载必须使用三极管、MOSFET或专用驱动芯片进行扩流。输入滤波对于连接机械开关如按键的输入引脚虽然PCA9574内部有简单的输入滤波器但对于严重的抖动最好在软件中增加去抖逻辑如延时10-20ms再采样或者在硬件上增加RC滤波电路如串联一个100Ω电阻并接一个100nF电容到地。5. 典型应用场景与实战代码5.1 场景一混合电压系统传感器接口需求主MCU工作在1.8V需要读取一个3.3V的温度传感器如DS18B20单总线协议和驱动一个3.3V的蜂鸣器。方案VDD接1.8VVDD(IO)接3.3V。P0引脚连接DS18B20的DQ线配置为开漏模式实际由PCA9574内部上拉。P1引脚连接蜂鸣器驱动三极管的基极配置为推挽输出。代码要点// 初始化 void Sensor_Interface_Init(void) { // 配置P0为输入用于读取DS18B20P1为输出用于驱动蜂鸣器 PCA9574_WriteRegister(REG_CONFIG, 0xFD); // 0b11111101, P1输出其余输入 // 禁用总线保持使能上拉/下拉 PCA9574_WriteRegister(REG_BKEN, 0x02); // 为P0DS18B20数据线配置内部上拉电阻 PCA9574_WriteRegister(REG_PUPD, 0x01); // 仅P0上拉 // 初始化P1输出低电平蜂鸣器关闭 PCA9574_WriteRegister(REG_OUTPUT, 0x00); } // 模拟DS18B20复位脉冲需要将P0临时切换为输出低电平 void DS18B20_Reset(void) { uint8_t cfg_backup, out_backup; // 备份当前配置和输出状态 PCA9574_ReadRegister(REG_CONFIG, cfg_backup); PCA9574_ReadRegister(REG_OUTPUT, out_backup); // 将P0配置为输出低电平 PCA9574_WriteRegister(REG_CONFIG, cfg_backup 0xFE); // P0设为输出 PCA9574_WriteRegister(REG_OUTPUT, out_backup 0xFE); // P0输出0 Delay_us(480); // 保持480us低电平 // 将P0恢复为输入带上拉 PCA9574_WriteRegister(REG_CONFIG, cfg_backup); PCA9574_WriteRegister(REG_OUTPUT, out_backup); Delay_us(70); // 等待DS18B20响应 // ... 后续读取存在脉冲和数据的代码需要频繁切换P0方向 }踩坑记录在模拟单总线协议时需要频繁切换引脚方向。务必注意每次从输出模式切换回输入模式前最好先读取一次输入寄存器或者确保在切换前该引脚的中断已被屏蔽否则极易产生伪中断。更稳妥的做法是在操作单总线器件期间暂时关闭该引脚的中断功能。5.2 场景二多按键扫描与中断唤醒需求一个电池供电的设备有8个独立按键。在休眠模式下MCU进入低功耗状态需要通过PCA9574的中断功能来唤醒MCU。方案VDD和VDD(IO)均接系统电源如3.3V。8个按键一端接GPIOP0-P7另一端接地。将P0-P7全部配置为输入并启用内部上拉电阻。按键未按下时引脚被上拉为高电平按下时被拉低到地。使能所有引脚的中断屏蔽寄存器MSK设为0x00并将INT引脚连接到MCU的外部中断输入引脚。代码要点void Keypad_InitForWakeup(void) { // 1. 所有引脚设为输入 PCA9574_WriteRegister(REG_CONFIG, 0xFF); // 2. 使能内部上拉因为按键是接地式的 PCA9574_WriteRegister(REG_BKEN, 0x02); // 使能PU/PD PCA9574_WriteRegister(REG_PUPD, 0xFF); // 全部上拉 // 3. 使能所有引脚的中断下降沿和上升沿都会触发 PCA9574_WriteRegister(REG_MASK, 0x00); // 全部不屏蔽 // 4. 读取一次输入端口清除可能存在的初始中断状态 uint8_t dummy; PCA9574_ReadInputPort(dummy); } // MCU外部中断服务程序 void EXTI_IRQHandler(void) { if(EXTI_GetFlagStatus(KEY_INT_PIN)) { uint8_t int_status, key_state; // 1. 读取中断状态寄存器可选用于判断哪个键按下 PCA9574_ReadRegister(REG_STATUS, int_status); // 2. 读取输入端口状态此操作会清除INT信号 PCA9574_ReadInputPort(key_state); // 3. 处理按键key_state中为0的位表示被按下的键 Process_KeyPress(~key_state); // 取反因为按下是低电平 EXTI_ClearFlag(KEY_INT_PIN); } }注意事项在这种应用中INT引脚是开漏输出必须连接一个上拉电阻通常4.7kΩ - 10kΩ到VDD。当任何按键状态变化时INT被内部拉低产生下降沿触发MCU中断。在中断服务程序中必须读取输入端口寄存器来清除中断否则INT会一直保持低电平。6. 常见问题排查与调试技巧在实际项目中应用PCA9574可能会遇到一些典型问题。下面是一个快速排查指南。现象可能原因排查步骤与解决方案I2C通信失败无应答1. 电源问题VDD/VDD(IO)未接通或电压不对。2. I2C地址错误。3.SDA/SCL上拉电阻缺失或阻值过大。4. 总线被锁死某个器件拉低了总线。1. 用万用表测量VDD、VDD(IO)、VSS引脚电压是否正常。2. 确认A0引脚电平计算正确的7位地址0x40或0x42。3. 检查SDA/SCL线上是否有4.7kΩ上拉电阻到VDD。4. 尝试逐个断开总线上的其他I2C设备或对MCU和PCA9574进行硬件复位。可以写入但读取的数据全为0xFF或0x001. 读操作时序错误未发送重复起始Repeated START。2. 在写命令字节后直接发送读地址没有先发停止条件或重复起始。1. 使用逻辑分析仪或示波器抓取I2C波形对照数据手册图13检查读时序是否正确。2. 确保代码中在写命令字节和读数据之间使用了正确的“写-读”序列Write followed by Read。INT引脚一直为低电平1. 发生了中断但未清除。2. 多个输入引脚状态同时变化且未处理。3.INT引脚外部上拉电阻损坏或未连接。1. 在中断服务程序中务必执行一次读取输入端口IN寄存器的操作。2. 读取INTS寄存器判断中断源并确保所有变化了的输入状态都被处理读IN寄存器。3. 检查INT引脚的上拉电阻。配置了内部上拉但输入引脚电平仍不稳定1. 内部上拉/下拉功能未正确使能BKEN寄存器配置错误。2. 外部电路驱动能力远强于内部100kΩ上拉/下拉。1. 确认配置顺序先设CFG为输入再设BKEN为0x02最后设PUPD。2. 用万用表测量引脚电压。如果外部是强驱动如MOSFET输出内部上拉/下拉的影响可以忽略应以外部电路为准。输出引脚驱动LED亮度不足PCA9574驱动能力有限源电流1mA灌电流3mA。1. 增大LED限流电阻会降低亮度减小电阻会增加电流但可能超负荷。计算电流I (VDD(IO) - Vf_led) / R。确保I小于3mA灌电流或1mA源电流。2. 对于需要更高亮度的LED必须使用三极管或MOSFET驱动。电平转换功能不正常1.VDD和VDD(IO)电压关系不满足要求。2. 两个电源域的地未连接好。1. 确保VDD(IO)VDD。例如MCU是1.8V外围是3.3V则VDD1.8VVDD(IO)3.3V。2. 用万用表蜂鸣档检查VSS芯片地与两个电源域的地是否都是导通的。使用“GPIO All Call”地址无效果1. 向地址0x00写数据时未将R/W位设为0写。2. 总线上有其他不兼容此命令的I2C设备干扰。1. 确认发送的全体呼叫地址字节是0x008位最后一位R/W0。2. 尝试单独与每个PCA9574通信确认其地址和功能正常再测试All Call。调试利器逻辑分析仪对于I2C通信问题一个几十块钱的USB逻辑分析仪配合PulseView或Saleae软件是无价之宝。它可以清晰地显示SDA、SCL线上的每一位数据、地址、ACK/NACK让你直观地看到是否发送了正确的设备地址、命令字节和数据以及从设备是否给出了应答。这是排查I2C问题最高效的方法。最后关于功耗PCA9574在待机时电流小于1μA这对于电池供电设备非常友好。但在计算系统总功耗时别忘了加上VDD(IO)上拉电阻的电流。例如如果8个输入都通过100kΩ上拉到3.3V且外部均为低电平那么仅上拉电阻就会消耗8 * (3.3V / 100kΩ) 0.264mA的电流。在深度休眠设计中需要权衡是否使用内部上拉或者考虑在MCU控制下彻底关断外围电路的电源。