第一章 课程导论与硬件准备
各位同学,欢迎来到《ESP32 I2C传感器驱动与数据采集开发实战》的第一章。
做嵌入式开发这些年,我越来越觉得I2C是个好东西。它只需要两根线,就能挂一堆传感器。你想想看,一个ESP32,接上温湿度、气压、加速度计,总共才用两个IO口。这性价比,没谁了。
这一章,我们先打好基础。把开发板、协议、传感器选型、接线、环境搭建这些事儿捋清楚。后面写驱动的时候,你才不会手忙脚乱。
1.1 ESP32开发板:为什么选它?
ESP32是乐鑫科技推出的双核MCU,带Wi-Fi和蓝牙。我最早用ESP8266做项目,后来换成ESP32,感觉就像从自行车换成了摩托车。性能翻倍,外设接口也多了不少。
具体到I2C这块,ESP32有两个硬件I2C控制器。你可以同时跑两路I2C总线,一路接高速传感器,一路接低速传感器。互不干扰。
| 参数 | ESP32 | 备注 |
|---|---|---|
| CPU | 双核 Xtensa LX6,最高240MHz | 够用 |
| I2C控制器 | 2个 | 可同时使用 |
| I2C速率 | 标准模式100kHz / 快速模式400kHz | 大部分传感器够用 |
| GPIO | 任意引脚可映射为SCL/SDA | 布线灵活 |
| 工作电压 | 3.3V | 注意传感器电平匹配 |
1.2 I2C协议基础:两根线的艺术
I2C,全称Inter-Integrated Circuit。说白了,就是飞利浦当年搞出来让芯片之间聊天的协议。
它只有两根线:
- SCL(串行时钟线) — 由主机控制,产生时钟脉冲
- SDA(串行数据线) — 双向数据线,主机和从机都能拉
这两根线都是开漏输出,所以必须接上拉电阻。我见过不少新手,焊好板子发现通信不了,查了半天,结果是忘了加上拉电阻。
I2C的通信流程,其实就这几步:
- 主机发送起始条件(SCL高电平时,SDA从高变低)
- 主机发送7位从机地址 + 1位读写位
- 从机应答(拉低SDA)
- 数据传输(每字节后跟一个应答位)
- 主机发送停止条件(SCL高电平时,SDA从低变高)
嗯,流程不复杂。但有个细节要注意:地址是7位的,但很多数据手册会把地址写成8位(左移一位后的值)。你写代码时一定要看清楚。
1.3 常用I2C传感器选型
市面上I2C传感器多得让人眼花。我挑几个课程里会用到的,也是我项目里用得最多的:
| 传感器 | 测量内容 | I2C地址 | 工作电压 | 精度 |
|---|---|---|---|---|
| SHT30 | 温湿度 | 0x44 / 0x45 | 2.4V - 5.5V | ±0.3°C / ±2%RH |
| BMP280 | 气压、温度 | 0x76 / 0x77 | 1.8V - 3.6V | ±1hPa |
| MPU6050 | 加速度、陀螺仪 | 0x68 | 2.4V - 3.6V | 16位ADC |
说个我自己的经历。有一次做环境监测节点,选了SHT30和BMP280。两个传感器挂同一条I2C总线上,地址不冲突。代码写起来很顺,数据也稳定。后来客户要加姿态检测,我又加了MPU6050。三个传感器,两根线,搞定。
1.4 硬件接线
接线其实很简单。但越简单的事,越容易出错。
标准接法:
- ESP32的GPIO21 → SCL(所有传感器的SCL并在一起)
- ESP32的GPIO22 → SDA(所有传感器的SDA并在一起)
- VCC → 3.3V(注意传感器的工作电压范围)
- GND → GND(共地!共地!共地!)
- SCL和SDA各接一个4.7kΩ上拉电阻到3.3V
ESP32的I2C引脚是可以任意映射的。你不一定非要用GPIO21和22。比如我有个项目,GPIO21和22被其他外设占了,我就把I2C映射到了GPIO16和17。代码里改一下引脚号就行。
1.5 开发环境搭建
课程里我会用两种环境:Arduino IDE和ESP-IDF。你选一个就行。
1.5.1 Arduino IDE(推荐新手)
Arduino IDE上手快,库多。我最早接触ESP32就是用Arduino IDE。
步骤:
- 下载安装Arduino IDE(官网直接下)
- 打开IDE,进入 文件 → 首选项 → 附加开发板管理器网址
- 填入:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - 工具 → 开发板 → 开发板管理器,搜索ESP32,安装
- 选择开发板:工具 → 开发板 → ESP32 Arduino → ESP32 Dev Module
装好后,写个简单的I2C扫描程序测试一下:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // SDA=21, SCL=22
Serial.println("I2C Scanner");
}
void loop() {
byte error, address;
int nDevices = 0;
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("Found at 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
nDevices++;
}
}
if (nDevices == 0) Serial.println("No devices found");
delay(5000);
}
1.5.2 ESP-IDF(进阶选择)
如果你要做产品,我建议用ESP-IDF。它更底层,控制力更强,资源占用也更小。
安装步骤:
- 去乐鑫官网下载ESP-IDF安装器(Windows)或使用命令行(Linux/Mac)
- 运行安装脚本,选择目标版本(建议用最新的稳定版)
- 设置环境变量:
export IDF_PATH=~/esp/esp-idf - 创建工程:
cp -r $IDF_PATH/examples/peripherals/i2c/i2c_simple . - 配置:
idf.py menuconfig→ 设置I2C引脚和速率 - 编译烧录:
idf.py build flash monitor
ESP-IDF的I2C驱动API比Arduino复杂一些,但功能更全。比如支持DMA传输、支持多主机模式。这些高级功能,我们后面章节会讲到。
1.6 本章小结
这一章我们聊了:
- ESP32为什么适合做I2C传感器采集
- I2C协议的核心流程:起始、地址、应答、数据、停止
- 三款常用传感器的选型对比
- 硬件接线要点和上拉电阻的选择
- Arduino IDE和ESP-IDF两种开发环境的搭建
嗯,内容不少。但这些都是基本功。后面每一章都会用到这些知识。
我建议你花点时间,把开发环境搭好,把传感器接好,跑通那个I2C扫描程序。当你看到串口输出"Found at 0x44"的时候,你就知道,硬件没问题了。