I2C — 读写 EEPROM
难度: ⭐⭐(需要了解 I2C 基本概念)
固件库: AT32F403A_407_Firmware_Library V2.2.2
源文件:project/at_start_f403a/examples/i2c/eeprom/src/main.c
这个实验是干嘛的?
EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种掉电不丢失的存储芯片。它不像 Flash 那样需要擦除整块扇区,可以逐字节读写,非常适合存储配置参数、校准数据、用户设置等小量关键数据。
AT24C02 是最经典的 EEPROM 芯片,容量 256 字节,I2C 接口,只要 2 根线就能通信。
本实验做的事情:
- 准备 3 组不同的测试数据
- 分别用轮询、中断、DMA 三种方式写入 EEPROM
- 读回数据并比对
- 三种方式都成功 → LED 亮
硬件准备
你需要一个 AT24C02 EEPROM 模块(淘宝 2~3 块):
|
|
重要:
- I2C 总线需要上拉电阻(一般 4.7KΩ)
- 大多数模块已经焊好了上拉电阻,不用你加
- 如果自己搭电路,SCL 和 SDA 各接一个 4.7K 上拉到 VCC
I2C 基础知识
I2C 只需要 2 根线就能连接多个设备:
| 信号 | 全称 | 说明 |
|---|---|---|
| SCL | Serial Clock | 时钟信号,主机产生 |
| SDA | Serial Data | 数据信号,双向 |
I2C 的核心概念
1. 主从模式
- 主机(Master):发起通信,产生时钟
- 从机(Slave):被动响应,每个从机有唯一地址
2. 7 位地址
- 每个 I2C 设备有一个 7 位地址(如 AT24C02 的地址是
0x50) - 一根总线上可以挂多个设备,靠地址区分
3. 读写操作
- 写操作:主机发送 [从机地址+W] + [数据]
- 读操作:主机发送 [从机地址+R],然后从机返回数据
I2C vs SPI 对比
| 特性 | I2C | SPI |
|---|---|---|
| 线数 | 2 根(SCL+SDA) | 4 根(SCK+MOSI+MISO+CS) |
| 速度 | 100K/400K/1M | 几十 MHz |
| 多设备 | 地址区分,同一总线挂多个 | 每个设备一根 CS 线 |
| 全双工 | 否(半双工) | 是 |
| 适用场景 | 低速传感器、EEPROM | 高速 Flash、LCD |
完整代码
|
|
代码分段讲解
1. I2C 地址
|
|
AT24C02 的 7 位地址是 0x50,左移 1 位变成 0xA0。为什么?
I2C 传输时,地址后面跟一个读写位:
- 写操作:
0x50 << 1 | 0 = 0xA0 - 读操作:
0x50 << 1 | 1 = 0xA1
2. GPIO 配置
|
|
I2C 必须用开漏输出! 为什么?
- I2C 总线上有多个设备,任何设备都可以拉低 SDA/SCL
- 开漏模式:只能拉低,不能主动拉高(靠上拉电阻拉高)
- 如果用推挽输出,两个设备同时输出不同电平会短路!
3. 三种传输模式
| 模式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 轮询 | CPU 不断检查标志位 | 简单直接 | 占用 CPU |
| 中断 | 传输完成触发中断 | CPU 可以做其他事 | 需要中断服务函数 |
| DMA | DMA 自动搬运数据 | CPU 完全不参与 | 配置复杂 |
4. 写入后延时
|
|
EEPROM 写入是一个内部编程过程,需要几毫秒。在编程期间,EEPROM 不会应答(NACK),主机必须等待。
实验现象
- 按下 USER 按键
- 三种模式依次写入并读回
- LED3 亮起 → 三种模式全部成功
- LED2 快闪 → 有失败,检查接线
常见问题
Q: I2C 通信超时?
- 检查上拉电阻(4.7KΩ)
- 检查地址是否正确(7 位 vs 8 位地址的区别)
- 检查 SCL/SDA 是否接反
Q: 写入后读出来不对?
- EEPROM 写入需要时间,写入后至少等 5ms 再读
- 检查 EEPROM 地址引脚(A0/A1/A2)是否与代码一致
Q: 7 位地址和 8 位地址的区别?
- 7 位地址:
0x50(芯片手册上的地址) - 8 位地址:
0xA0(左移 1 位,包含读写位) - 不同库函数可能要求不同格式,注意区分
小结
| 概念 | 说明 |
|---|---|
| I2C | 2 线制低速通信总线 |
| EEPROM | 掉电不丢失,逐字节读写 |
| 开漏输出 | I2C 必须用,避免短路 |
| 上拉电阻 | 4.7KΩ,必须有 |
| 7 位地址 | 芯片手册上的地址 |
| 写入延时 | EEPROM 编程需要几毫秒 |
学了 I2C 能做什么?
I2C 是连接"低速外设"的万能总线,几乎所有传感器都支持 I2C:
传感器
| 项目 | 原理 | 难度 |
|---|---|---|
| 温湿度检测 | SHT30/DHT20 + I2C → 温湿度数据 | ⭐⭐ |
| 气压检测 | BMP280 + I2C → 气压/海拔 | ⭐⭐ |
| 光照检测 | BH1750 + I2C → 光照强度 | ⭐ |
| 加速度/陀螺仪 | MPU6050 + I2C → 6 轴姿态 | ⭐⭐⭐ |
| RTC 时钟 | DS3231 + I2C → 精确时间 | ⭐⭐ |
| 磁场检测 | QMC5883L + I2C → 电子罗盘 | ⭐⭐⭐ |
| 触摸检测 | TTP223 电容触摸 + I2C | ⭐⭐ |
存储与显示
| 项目 | 原理 | 难度 |
|---|---|---|
| 配置参数存储 | AT24C02 + I2C → 存校准数据 | ⭐ |
| OLED 显示 | SSD1306 + I2C → 0.96 寸 OLED | ⭐⭐ |
| LCD 显示 | I2C 接口的字符 LCD | ⭐⭐ |
实际应用场景
- 气象站:I2C 温湿度 + 气压 + 光照 → 环境监测
- 平衡车:I2C MPU6050 → 姿态检测 + PID 控制
- 智能手表:I2C 心率 + 加速度 + RTC → 健康监测
- 工业仪表:I2C ADC(ADS1115)→ 高精度电压测量
核心思路:I2C 的核心优势是省线。2 根线就能挂 128 个设备。传感器、EEPROM、RTC、OLED……几乎所有低速外设都用 I2C。掌握了 I2C,你就有了连接整个传感器世界的能力。
下一步:学会了 I2C,可以学 TIM PWM 输出,用定时器生成 PWM 信号控制 LED 亮度、电机转速。