树莓派IO不够用?一招搞定:用PCF8574轻松扩展64个GPIO!

你有没有遇到过这样的情况——
手里的树莓派正忙着控制几盏灯、几个继电器,还想接几个按键和传感器,结果发现GPIO引脚早就“捉襟见肘”?明明硬件都准备好了,却因为少了两三个IO口,项目卡在最后一步。

别急,今天我们就来解决这个嵌入式开发中的经典难题: 如何在不换主板、不增加复杂电路的前提下,让树莓派的IO口“凭空多出几十个”?

答案就是—— PCF8574 。一块不到五块钱的芯片,通过I2C总线,就能给你带来8个额外的可编程IO口。而且,还能级联8片,一口气扩展到 64个IO !是不是听起来有点不可思议?

接下来,我会带你从零开始,讲清楚这颗“小芯片”是怎么做到的,怎么接、怎么写代码、有哪些坑要避开,并告诉你它到底适合哪些真实项目场景。


为什么树莓派总嫌IO少?

先说个现实:标准树莓派(比如3B+或4B)虽然标称有40个Pin,但真正能当通用GPIO用的也就 17个左右 。剩下的不是被UART、SPI、I2C占了,就是供电脚或者保留引脚。

一旦你要做点复杂的控制——比如智能家居面板、工业监测终端、多路数据采集系统——这点IO根本不够看。

常见的解决方案无非几种:
- 换成更高端的开发板(成本上升)
- 加一个STM32做协处理器(复杂度飙升)
- 用移位寄存器(如74HC595)模拟并行输出(软件时序难调)

但如果你追求的是 低成本、低功耗、易维护 的方案,那最合适的还是—— 基于I2C的IO扩展器 ,而其中最具代表性的,就是 PCF8574 。


PCF8574:一颗芯片,8个IO,I2C驱动

它是什么?

PCF8574 是 NXP 推出的一款 CMOS 集成电路,本质是一个 8位远程I/O扩展器 ,专为 I2C 总线设计。你可以把它理解成一个“远程的小型GPIO模块”,由树莓派通过两根线(SDA+SCL)远程操控它的8个引脚(P0~P7)。

每个引脚都可以配置为输入或输出,支持上拉,还能触发中断通知主控。最关键的是: 它只需要占用树莓派的I2C接口,就能提供8个新IO !

它是怎么工作的?

我们拆解一下它的内部逻辑:

  1. 通信靠I2C :树莓派作为主设备,通过SDA(数据)、SCL(时钟)与PCF8574建立连接。
  2. 地址可配置 :芯片有3个地址引脚 A0/A1/A2,接地或接高电平可以设置不同地址( 0x20 ~ 0x27 ),最多挂8片。
  3. 读写操作简单粗暴 :
    - 写操作:发送1字节 → 控制P0~P7输出高低电平
    - 读操作:读取1字节 ← 获取当前所有引脚的状态

⚠️ 注意:PCF8574没有独立的方向寄存器!它的IO方向是靠“读-改-写”机制隐式决定的。
简单来说:你想让它输出?那就写数据;你想读输入?直接读就行。外部电路决定了它是输入还是输出状态。

关键参数一览

特性 参数说明
工作电压 2.5V ~ 6V(完美兼容树莓派3.3V)
通信速率 支持100kHz(标准模式)和400kHz(快速模式)
输出类型 开漏(Open-Drain),必须外加上拉电阻
每引脚驱动能力 最大吸收电流约25mA
总电流限制 建议不超过100mA
中断输出 INT引脚,输入变化时拉低,可用于唤醒主控

这些特性让它特别适合电池供电、低功耗、多节点的嵌入式场景。


和其他方案比,它强在哪?

我们来看一张实战对比表:

对比项 传统MCU扩展 移位寄存器(74HC595) PCF8574
通信方式 并行/串行 SPI模拟 原生I2C
扩展效率 高但贵 多片级联麻烦 单总线最多8片
成本 高(需额外MCU) 中等(¥2~5) 极低(<¥5)
软件开销 需写驱动 需精确时序控制 Linux内核原生支持
功耗 较高 中等 极低(典型10μA)
开发难度 高 中 低

结论很明显:对于大多数中小型项目,尤其是原型验证、教育实验、家庭自动化这类场景, PCF8574 是性价比之王 。


实战演示:Python控制LED流水灯

下面这段代码,将展示如何使用 Python 控制 PCF8574 实现一个简单的 8位LED流水灯效果 。

import smbus
import time

# 初始化I2C总线(树莓派通常使用bus 1)
bus = smbus.SMBus(1)

# PCF8574默认地址(A0=A1=A2=GND → 地址0x20)
PCF8574_ADDR = 0x20

def write_pcf8574(data):
    """
    向PCF8574写入一个字节,控制P0-P7输出
    :param data: 0x00 ~ 0xFF,对应8个引脚电平
    """
    try:
        bus.write_byte(PCF8574_ADDR, data)
        print(f"Sent data: 0x{data:02X}")
    except Exception as e:
        print("Write error:", e)

def read_pcf8574():
    """
    读取PCF8574当前输入状态
    :return: 返回一字节数据,表示P0-P7当前电平
    """
    try:
        data = bus.read_byte(PCF8574_ADDR)
        print(f"Read data: 0x{data:02X}")
        return data
    except Exception as e:
        print("Read error:", e)
        return None

# 主程序:循环点亮LED(共阴极接法,低电平点亮)
if __name__ == "__main__":
    try:
        while True:
            for i in range(8):
                # 只让第i个引脚为低电平,其余为高
                output_val = 0xFF & ~(1 << i)
                write_pcf8574(output_val)
                time.sleep(0.2)  # 每次延时200ms
    except KeyboardInterrupt:
        print("\nExiting...")
        write_pcf8574(0xFF)  # 关闭所有LED

📌 关键说明 :
- 使用 smbus 库进行I2C通信,简洁高效。
- write_byte(addr, data) 直接写入一个字节,即可控制全部8个IO。
- LED建议串联330Ω~1kΩ限流电阻。
- 必须给PCF8574的VCC和GND之间加0.1μF去耦电容 ,否则容易受干扰。


如何在树莓派上启用I2C?

很多新手卡在这一步。其实非常简单,只需四步:

✅ 第一步:启用I2C接口

sudo raspi-config

进入 Interface Options → I2C → 选择 Yes 启用。

✅ 第二步:安装必要工具

sudo apt update
sudo apt install python3-smbus i2c-tools

✅ 第三步:检测设备是否在线

sudo i2cdetect -y 1

如果一切正常,你会看到类似这样的输出:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
...

看到 20 位置有个 20 ?恭喜,你的PCF8574已经被识别了!

📌 提示:如果没显示,检查接线、电源、上拉电阻是否正确。

✅ 第四步(可选):免sudo运行

将当前用户加入i2c组,避免每次都要用root权限运行脚本:

sudo usermod -aG i2c pi

重启后生效。


硬件设计要点:别踩这些坑!

再好的软件也救不了错误的硬件连接。以下是几个关键注意事项:

🔌 1. 上拉电阻不可少

PCF8574 的 SDA 和 SCL 是开漏结构, 必须外接上拉电阻 到 VCC(一般3.3V)。
推荐阻值: 4.7kΩ ~ 10kΩ 。可以直接焊接在PCB上,或使用I2C模块自带的电阻。

🔋 2. 电源去耦很重要

在PCF8574的VCC引脚附近放置一个 0.1μF陶瓷电容 到地,滤除高频噪声,防止通信失败。

🧩 3. 地址冲突怎么办?

多个PCF8574级联时,一定要确保每片地址唯一。通过 A0/A1/A2 引脚接地或接VCC 设置不同组合:

A2 A1 A0 地址
0 0 0 0x20
0 0 1 0x21
0 1 0 0x22
… … … …
1 1 1 0x27

例如,第一片全接地 → 0x20 ,第二片 A0接VCC → 0x21 ,以此类推。

⚡ 4. 驱动能力别超标

虽然每个引脚能吸25mA电流,但整个芯片建议总电流不要超过 100mA 。如果你要驱动多个大功率负载(如大电流LED或继电器线圈),建议加三极管或MOSFET做缓冲。

🔔 5. 中断功能怎么用?

PCF8574 的 INT 引脚是个开漏输出,当任意输入引脚状态改变时,它会拉低,可用于触发树莓派某个GPIO的中断。

应用场景举例:
- 检测紧急停止按钮按下
- 实时上报传感器状态变化
- 避免轮询浪费CPU资源

只需将 INT 连接到树莓派的一个GPIO(如GPIO17),并在程序中设置边沿触发中断回调函数即可。


典型应用场景:不只是点灯那么简单

你以为PCF8574只能用来点LED?太小看它了。来看看它在实际项目中的玩法:

🏠 智能家居控制面板

  • 多路继电器控制灯具、插座、窗帘
  • 按键矩阵实现本地手动开关
  • 一路PCF8574负责输出,另一路负责读取物理按键状态

🏭 工业监测终端

  • 扩展多路数字输入,用于采集设备启停信号
  • 控制报警灯、蜂鸣器等执行单元
  • 结合Modbus网关,实现边缘侧IO聚合

🧪 教学实验平台

  • 学生动手搭建IO扩展系统
  • 理解I2C协议、地址编码、总线负载等核心概念
  • 成本低,损坏也不心疼

总结:一个小芯片,撬动大系统

回过头看,PCF8574的成功之处在于它的“ 极致平衡 ”:

  • 硬件极简 :仅需两根线 + 几个电阻
  • 软件友好 :Linux原生支持,几行Python就能跑通
  • 成本低廉 :单价不足5元人民币
  • 扩展性强 :单总线最多扩展64个IO
  • 适用面广 :从学生实验到工业现场都能胜任

虽然现在也有更强大的替代品(比如 MCP23017 支持更多功能和中断配置),但在入门级应用中, PCF8574 依然是那个“够用、好用、便宜”的首选方案 。

下次当你面对“IO不够”的困境时,不妨试试这块小芯片。也许只花一顿早餐的钱,就能让你的树莓派项目起死回生。


💡 互动时间 :
你在项目中用过PCF8574吗?是用来控制什么外设的?有没有遇到奇怪的通信问题?欢迎在评论区分享你的经验!

更多推荐