I²C 总线连接多个传感器

📅 2026-05-12 · 📂 硬件编程 · ⏱ 阅读约 7 分钟

📺 B站推荐视频:ESP32 入门教程

概述

I²C(Inter-Integrated Circuit,读作"I方C"或"I2C")是最常用的传感器通信总线之一。只需 2 根线(SDA/SCL),就能挂载上百个设备。本篇带你同时连接 OLED 屏幕和 BME280 温湿度气压传感器。

学习目标:理解 I²C 协议原理(地址、读写时序),掌握 Wire 库,学会 I²C 扫描器调试。

物料清单

OLED ~12元,BME280 ~8元,淘宝成套购买。

I²C 原理

I²C 总线由两根线组成:SDA(数据线)和 SCL(时钟线)。每个从设备有唯一的 7 位地址。主设备(ESP32)发起通信,从设备响应。

信号方向说明
SDA双向数据(地址+数据位+ACK)
SCL主→从时钟(100/400kHz)
上拉电阻-ESP32内部有,外部可不接

接线图

🔌 双传感器 I²C 并联
     ESP32              OLED(SSD1306)       BME280
  ┌─────────┐        ┌──────────┐       ┌──────────┐
  │ 3.3V ───┼────────┼── VCC ───┼───────┼── VIN    │
  │ GND  ───┼────────┼── GND ───┼───────┼── GND    │
  │ SDA(21)─┼────────┼── SDA ───┼───────┼── SDA    │
  │ SCL(22)─┼────────┼── SCL ───┼───────┼── SCL    │
  └─────────┘        └──────────┘       └──────────┘
  
  ⚠️ 所有设备 I²C 地址必须不同!OLED=0x3C, BME280=0x76

I²C 地址扫描器(调试必备)

// I2C_Scanner.ino — 扫描总线上所有设备地址 #include <Wire.h> void setup() { Serial.begin(115200); Wire.begin(); Serial.println("I²C 扫描中..."); for (uint8_t addr = 1; addr < 127; addr++) { Wire.beginTransmission(addr); if (Wire.endTransmission() == 0) { Serial.printf("✓ 找到设备 0x%02X ", addr); } } Serial.println("扫描完成"); } void loop() {}

实战:OLED+BME280 双传感器

// 需要安装库: Adafruit_SSD1306, Adafruit_BME280, Adafruit_GFX #include <Wire.h> #include <Adafruit_SSD1306.h> #include <Adafruit_BME280.h> Adafruit_SSD1306 oled(128, 64, &Wire, -1); Adafruit_BME280 bme; void setup() { Wire.begin(); oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); bme.begin(0x76); oled.clearDisplay(); } void loop() { float t = bme.readTemperature(); float h = bme.readHumidity(); float p = bme.readPressure() / 100.0; oled.clearDisplay(); oled.setTextSize(1); oled.setCursor(0,0); oled.printf("Temp: %.1f C ", t); oled.printf("Humi: %.1f %% ", h); oled.printf("Pres: %.1f hPa ", p); oled.display(); delay(2000); }

常见问题

⚠️ 地址冲突:同一型号传感器地址相同(如两个 OLED 都是 0x3C),无法挂在同一总线上。解决方案:部分模块有地址选择跳线(如 0x3C/0x3D),或使用 I²C 多路复用器 TCA9548A。
💡 上拉电阻:ESP32 内部有弱上拉,短距离连接够用。长线(>30cm)或高速(400kHz)时建议外部加 4.7kΩ 上拉。