如何配置树莓派4 GPIO引脚实现双板I2C主从通信
树莓派4间I2C主从通信实现方案
树莓派4的硬件I2C控制器仅支持主机模式,无法直接作为I2C从机运行——你之前用的多路复用桥(如PCA954x系列)是用来扩展主机的I2C通道,并非实现主从转换,所以效果不佳是正常的。以下是两种可行的解决方案:
方案一:软件模拟I2C从机(无需额外硬件)
利用树莓派的通用GPIO引脚模拟I2C从机逻辑,无需额外芯片:
- 配置软件I2C总线
- 编辑
/boot/config.txt,注释掉硬件I2C启用项dtparam=i2c_arm=on,添加软件I2C配置:
(此处选GPIO23/24作为软件I2C的SDA/SCL,可根据未保留引脚自行调整)dtoverlay=i2c-gpio,bus=3,i2c_gpio_sda=23,i2c_gpio_scl=24 - 重启树莓派:
sudo reboot
- 编辑
- 从机端实现逻辑
安装依赖并编写Python代码模拟从机:
示例从机代码:sudo apt-get install python3-smbus python3-devfrom smbus2 import SMBus, i2c_msg import time SLAVE_ADDR = 0x48 # 自定义从机地址,避免冲突 BUS_NUM = 3 def run_slave(): bus = SMBus(BUS_NUM) while True: try: # 接收主机发送的数据 recv = i2c_msg.read(SLAVE_ADDR, 4) bus.i2c_rdwr(recv) print(f"Received data: {list(recv)}") # 向主机发送响应 send = i2c_msg.write(SLAVE_ADDR, [0x01, 0x02]) bus.i2c_rdwr(send) except Exception as e: print(f"Error: {str(e)}") time.sleep(0.1) if __name__ == "__main__": run_slave() - 主机端配置与代码
- 确保主机硬件I2C已启用(
/boot/config.txt中dtparam=i2c_arm=on未被注释),重启后用i2cdetect -y 1确认总线正常 - 示例主机代码:
from smbus2 import SMBus, i2c_msg import time SLAVE_ADDR = 0x48 BUS_NUM = 1 def run_master(): bus = SMBus(BUS_NUM) while True: # 发送数据到从机 send = i2c_msg.write(SLAVE_ADDR, [0x00, 0x01]) bus.i2c_rdwr(send) # 接收从机响应 recv = i2c_msg.read(SLAVE_ADDR, 2) bus.i2c_rdwr(recv) print(f"Slave response: {list(recv)}") time.sleep(1) if __name__ == "__main__": run_master()
- 确保主机硬件I2C已启用(
- 硬件连接
- 主机SDA(GPIO2)→ 从机软件I2C SDA(GPIO23)
- 主机SCL(GPIO3)→ 从机软件I2C SCL(GPIO24)
- 两块树莓派的GND引脚必须连接(共地)
方案二:使用I2C主从转换桥芯片(适合高带宽场景)
如果需要更快的通信速率,可选用专门的I2C主从转换桥(而非多路复用桥),比如PCA9540:
- 硬件连接
- 主机SDA/SCL → PCA9540的主机侧SDA/SCL引脚
- PCA9540的从机侧SDA/SCL → 从机树莓派的软件I2C引脚(同方案一的GPIO23/24)
- PCA9540的VCC接3.3V,GND与两块树莓派共地
- 配置桥芯片
通过主机I2C总线发送配置命令,启用主从转换模式:
(0x70是PCA9540默认地址,可通过硬件引脚修改)i2cset -y 1 0x70 0x01 - 从机端逻辑
同方案一的软件I2C从机代码即可
关键注意事项
- 软件模拟I2C的速率上限约100kHz,适合低数据量场景;用主从桥可接近硬件I2C速率
- 自定义从机地址前,用
i2cdetect -y <总线号>排查总线上的设备地址,避免冲突 - 所有连接必须使用3.3V电平,禁止接入5V信号损坏树莓派GPIO
内容的提问来源于stack exchange,提问作者Shreyanka Kumbar
相关产品推荐
相关产品推荐

