EEPROM 电路设计指南
I²C 24Cxx / SPI 25xx / Microwire 93xx / UNI/O 11xx / 并行 28Cxx · FRAM · NVSRAM 对比与选型 | 编制日期 2026-09-23 | 版本号 Rev 1.0
0 · 文档说明
适用范围
- 本文针对串行 / 并行 EEPROM(Electrically Erasable PROM,电可擦除可编程只读存储器)的硬件电路设计,覆盖 128 bit ~ 2 Mb(16 B ~ 256 KB)常见容量段,接口涵盖 I²C(24Cxx / 24AAxx / 24LCxx)、SPI(25AA / 25LC xx)、Microwire(93xx)、UNI/O(11xx)与并行总线(28Cxx)。
- 适用对象:MCU / SoC / FPGA / 专用 ASIC 的小容量非易失参数存储——校准数据、序列号、MAC 地址、运行计数器、用户配置、故障日志、EDID / SPD / OTP 等。
- 内容包含:选型对比、封装引脚、电气参数、四种串行协议细节、电源与掉电保护、典型电路(内联原理图)、I²C 上拉电阻与总线负载计算、Layout、信号完整性、可靠性、生产、排查与检查清单。
- 同时给出 FRAM(铁电存储器)与 NVSRAM(非易失 SRAM)作为 EEPROM 替代方案的对比与替换注意事项。
- 不包含:文件系统实现、具体厂商寄存器全表、I²C/SPI 主机控制器 IP 设计。所有参数一律以目标型号 datasheet 为准。
本系列其他文档
| 文档 | 器件类型 | 关注重点 |
|---|---|---|
| SPI NOR 电路设计指南 | 串行 NOR Flash | Quad/QPI 提速、dummy cycles、XIP、DPD 低功耗 |
| SPI NAND 电路设计指南 | 串行 NAND Flash | 页/块管理、片内 ECC、坏块表、主机 FTL |
| 并行NAND (PPI NAND) 电路设计指南 | 8/16 位并行 NAND | 宽总线时序、ECC 引擎、40+ 引脚 Layout |
| eMMC 电路设计指南 | eMMC 5.0/5.1 | HS200/HS400、1.8 V VCCQ、DS 选通与等长 |
| SD NAND 电路设计指南 | 贴片式 SD NAND | SPI/SDIO 双模式、无休眠指令、VCC 负载开关断电 |
| NAND MCP 电路设计指南 | 多芯片合封存储 | 多 die 与多 CE、双电源轨、HDI 扇出 |
| 并行NOR (PPI NOR) 电路设计指南 | 并行 NOR Flash | 异步读时序、XIP、等待周期、总线扩展 |
| PSRAM 电路设计指南 | 伪静态 RAM | OPI/HyperBus、刷新与延迟周期、XIP 与帧缓存 |
| DDR2 电路设计指南 | DDR2 SDRAM | SSTL_18、T 分支拓扑、VTT 端接、ODT |
| DDR3 电路设计指南 | DDR3 / DDR3L | Fly-by 拓扑、write leveling、动态 ODT |
| DDR4 电路设计指南 | DDR4 SDRAM | POD12、bank group、DBI、2D 训练 |
| DDR5 电路设计指南 | DDR5 SDRAM | 双子通道、On-DIMM PMIC、DFE、同帧 ECC |
| EEPROM 电路设计指南 本文 | EEPROM | I²C/SPI 接口、上拉电阻与总线电容、页写与写保护 |
· 数据量 ≤ 256 KB、需要频繁改写单个字节/几个字节、要求 10 年以上保持 → I²C 或 SPI EEPROM(参数、校准值、序列号、计数器)。
· 改写极频繁(每秒数百次以上)、要求写操作无等待、要求超低功耗或抗辐射 → FRAM(FM24CL64 / MB85RC 系列),写入无 tWR 等待, endurance 10¹² 以上。
· 要求 SRAM 级随机写速度 + 掉电自动保存、且能接受电池/电容后备 → NVSRAM(并行/SPI nvSRAM),代价是成本最高。
· 代码存储、XIP、字库、固件 → SPI NOR Flash;EEPROM 每 KB 成本太高,不适合放代码。
· 容量 ≥ 128 MB 的数据/文件系统 → SPI NAND / eMMC / SD NAND。
一句话结论:EEPROM 的核心价值是"按字节改、按字节保持、接口简单、成本极低",短板是写周期毫秒级、总容量小。
① 页写回卷(Page Write Roll-over):一次页写超过页边界时,多出的字节会从本页起始地址覆写,而不是翻到下一页——数据被静默覆盖,不报错。
② A2/A1/A0 不是永远都是地址位:24C04/08/16 把低位地址引脚改作内部页地址 P0/P1/P2,同总线可挂器件数从 8 个降到 4 / 2 / 1 个。
③ 写周期内掉电:tWR 期间 VCC 跌落到写阈值以下,正在写的字节内容不确定,严重时可能破坏同一页内其他字节——硬件必须保证写期间电源稳定。
1 · 器件基础
1.1 定位与选型对比
EEPROM 在整个存储器谱系里的位置很明确:容量最小、每 KB 最贵,但可以按字节改写、无需先擦除、接口最简单、掉电后数据保持最久。下面把它与常见的替代 / 相邻方案横向对比。
| 对比项 | EEPROM (24Cxx / 25xx) | FRAM (FM24CL64 等) | NVSRAM (nvSRAM) | SPI NOR Flash | SPI NAND Flash |
|---|---|---|---|---|---|
| 常见容量 | 128 bit ~ 2 Mb (16 B ~ 256 KB) | 4 Kb ~ 4 Mb (512 B ~ 512 KB) | 64 Kb ~ 16 Mb (8 KB ~ 2 MB) | 512 Kb ~ 2 Gb (64 KB ~ 256 MB) | 1 Gb ~ 8 Gb (128 MB ~ 1 GB) |
| 接口 | I²C / SPI / Microwire UNI-O / 并行 | I²C / SPI / 并行 | 并行 / SPI | SPI 1/2/4 线 | SPI 1/4 线 |
| 字节写 | 支持无需预擦除 直接覆盖写 | 支持与 RAM 同速 | 支持SRAM 时序 | 不支持须先擦除 4 KB 扇区 | 不支持须先擦除 128 KB 块 |
| 擦写次数 (endurance) | 10⁶ 次 (部分 4×10⁶) | 10¹² ~ 10¹⁴ 工程上视为无限 | 写无限 存储周期 10⁵ ~ 10⁶ | 10⁵ 次 | 10⁴ ~ 10⁵ 次 |
| 写入时间 | 3 ~ 10 ms / 页或字节 typ 5 ms | 总线速率级 无写等待 | 55 ~ 70 ns(SRAM 写) Store 8 ~ 25 ms | 页编程 0.4 ~ 3 ms + 扇区擦除 30 ~ 100 ms | 页编程 200 ~ 600 µs + 块擦除 2 ~ 4 ms |
| 写后是否需轮询 | 需要ACK 轮询 / 延时 | 不需要 | 需要(Store 期间) | 需要(WIP 位) | 需要(OIP 位) |
| 数据保持 | 100 年@25 °C (部分 40 / 200 年) | 10 ~ 100 年 (与写入次数耦合) | 20 ~ 100 年 (依赖内部非易失单元) | 20 年 @常温 | 5 ~ 10 年 |
| 读电流 | 0.4 ~ 2 mA @400 kHz | 0.1 ~ 0.4 mA @1 MHz | 10 ~ 40 mA | 15 ~ 25 mA @104 MHz Quad | 15 ~ 30 mA |
| 写电流 | 2 ~ 3 mA (内部电荷泵) | 与读相当 | 20 ~ 50 mA (Store 峰值更高) | 20 ~ 35 mA | 20 ~ 40 mA |
| 待机电流 | 1 ~ 5 µA 低压型号 < 1 µA | 3 ~ 100 µA | µA 级(休眠) mA 级(工作) | 10 ~ 50 µA | 10 ~ 100 µA |
| 每 KB 成本 | 最高 | 高(约 EEPROM 3~8 倍) | 极高 | 中 | 最低 |
| 抗干扰 / 软错误 | 好 | 好(可选抗辐射型号) | SRAM 模式有 SEU 风险 | 好 | 需 ECC |
| 典型用途 | 参数、校准、SN、 EDID / SPD、计数器 | 高频数据记录、 电表 / 医疗 / 黑匣子 | 高速掉电保存、 替代电池 SRAM | 代码、XIP、字库 | 大容量数据 |
① 真正的按字节改写:写 1 个字节与写 1 页耗时相同(都是 tWR ≈ 5 ms),且不需要先擦除,不像 Flash 必须"擦除—编程"两步。
② 数据保持 100 年:电荷存储在浮栅 + 隧道氧化层,常温保持期远超 NOR(20 年)与 NAND(5~10 年),适合产品全生命周期不再更新的校准数据、序列号。
③ 接口成本最低:I²C 型只占 2 个 MCU 引脚(SCL / SDA),可与 RTC、传感器、IO 扩展器、PMIC 共用同一条总线,8 脚封装甚至 5 脚 SOT-23 就能解决。
· 每秒改写超过十几次:tWR 5 ms 意味着理论上限约 200 次/秒,而 10⁶ 次 endurance 在 1 次/秒下约 11.6 天就耗尽——必须换 FRAM,或做环形磨损均衡(见 8.4)。
· 容量需求 > 256 KB:成本会失控,应选 SPI NOR。
· 写延迟不可接受(如掉电瞬间要保存一大块 RAM 镜像):5 ms/页意味着保存 4 KB 需 16 次页写 ≈ 80 ms,需要非常大的储能电容;此时 NVSRAM 的硬件 Store(8 ~ 25 ms 保存整片)更合适。
FRAM 替代 EEPROM(FM24CL64 / MB85RC 系列)的优劣
| 维度 | FRAM 相对 EEPROM 的表现 | 工程结论 |
|---|---|---|
| 软件兼容性 | I²C FRAM(如 FM24CL64,64 Kb)在协议层与 24Cxx 兼容,控制字节同为 1010 + A2A1A0 + R/W;SPI FRAM 与 25xx 指令集兼容 | 可原位替换多数仅需删除 tWR 轮询 |
| 写速度 | 写操作在总线速率内完成,无 tWR,无需 ACK 轮询 | 吞吐提升 100 倍以上 |
| 写功耗 | 无电荷泵高压脉冲,单字节写能耗低 1 ~ 2 个数量级 | 电池 / 能量采集场景优势明显 |
| endurance | 10¹² ~ 10¹⁴ 次 | 无需磨损均衡 |
| 页写回卷 | FRAM 不分页,连续写可跨越整片,无回卷陷阱 | 简化驱动 |
| 容量 | 主流 4 Kb ~ 4 Mb,2 Mb 以上选择少 | 大容量受限 |
| 成本 | 约 EEPROM 的 3 ~ 8 倍 | 仅在高改写频率场景划算 |
| 数据保持 | 标称 10 年(85 °C)~ 100 年(依型号),读为破坏性读出(器件内部自动回写) | 关键场合仍需冗余 |
| 焊接 / ESD | 铁电材料对高温回流敏感(多标 MSL3,回流峰值与次数受限),ESD 等级略低 | 须严格遵守厂家回流曲线 |
| 引脚差异 | 部分 FRAM 的 A0/A1/A2 定义与同容量 EEPROM 不同,WP 极性也可能相反 | 必须逐脚核对 |
1.2 封装与引脚定义
上图是最常见排布,但不能直接当作通用库。实际差异至少包括:
· A0/A1/A2 不一定都是地址脚:24C04 起低位地址脚被改作内部页地址(见 1.4),24C16 三个脚全部失效;
· WP 极性不同:I²C 24Cxx 的 WP 高电平保护(部分型号为低电平保护或支持反向配置);SPI 25xx 的 WP# 低电平保护,两者相反;
· 部分小容量型号把 A0 定义为 NC 或 DC(不连接),悬空与接地的表现不同,必须按手册处理;
· SOT-23-5 / DFN-8 / WLCSP 的引脚编号顺序与 SOP-8 无对应关系;
· 带 EUI / MAC 地址的型号(如 24AA02E48)内部高半区出厂写保护,且器件地址引脚可能被 EUI 功能占用。
规则:每一个新型号都必须逐脚核对目标 datasheet 的 Pin Configuration 章节,并在原理图库中标注型号与文档版本号。
引脚功能表(I²C SOP-8,以 24C02 为例)
| 脚位 | 名称 | 方向 | 说明与设计要求 |
|---|---|---|---|
| 1 | A0 | 输入 | 器件地址最低位。严禁悬空,直接接地或接 VCC(建议串 0 Ω 便于改配置) |
| 2 | A1 | 输入 | 器件地址位 1。同上 |
| 3 | A2 | 输入 | 器件地址位 2。24C16 上此脚为 NC,多数手册建议接地 |
| 4 | GND(VSS) | 电源 | 地,短粗走线直连地平面,去耦电容回流路径最短 |
| 5 | SDA | 开漏双向 | 串行数据。必须总线上拉(4.7 kΩ @100 kHz / 2.2 kΩ @400 kHz,见第 5 章精确计算) |
| 6 | SCL | 开漏输入 | 串行时钟。必须总线上拉;不开漏推挽驱动会造成总线冲突 |
| 7 | WP | 输入 | 硬件写保护,高电平禁止写。严禁悬空:建议 10 kΩ 下拉(默认可写)或 10 kΩ 上拉(默认保护),量产方案用 MCU GPIO 控制 |
| 8 | VCC(VDD) | 电源 | 电源,0.1 µF(X7R,0402/0603)紧靠此脚,回流焊后不可省 |
引脚功能表(SPI SOP-8,以 25AA / 25LC 系列为例)
| 脚位 | 名称 | 方向 | 说明与设计要求 |
|---|---|---|---|
| 1 | CS#(/CS) | 输入 | 片选,低有效。必须 10 kΩ 上拉到 VCC,保证上电与 MCU IO 未初始化期间不被误选中;每字节/每指令边界必须拉高 |
| 2 | SO(MISO) | 输出(三态) | 数据输出;CS# 无效时高阻,可与其它 SPI 从机共用 |
| 3 | WP# | 输入 | 硬件写保护,低电平禁止写状态寄存器(配合 WPEN 位);建议 10 kΩ 上拉或 GPIO 控制 |
| 4 | GND(VSS) | 电源 | 地 |
| 5 | SI(MOSI) | 输入 | 数据输入;建议主控侧串 22 ~ 33 Ω |
| 6 | SCK | 输入 | 串行时钟。不上拉;建议主控侧串 22 ~ 33 Ω |
| 7 | HOLD# | 输入 | 暂停传输(低有效,期间可释放总线给其它从机)。不用时必须上拉,否则通信永久失败 |
| 8 | VCC(VDD) | 电源 | 电源,0.1 µF 紧靠此脚 |
SPI EEPROM 的 HOLD# 为低电平时器件忽略 SCK 并保持当前状态机,若此脚因未焊接 / 虚焊 / 未上拉而处于浮空低电平,表现为"读写全部返回 0x00 或 0xFF 且不报错",极难定位。规则:HOLD# 与 WP# 必须显式上拉(10 kΩ)或由 MCU GPIO 驱动,禁止 NC 悬空。
常见封装与尺寸
| 封装 | 本体尺寸 | 脚距 | 适用容量 / 特点 |
|---|---|---|---|
| PDIP-8 | 9.2 × 6.4 mm | 2.54 mm | 直插,开发板 / 小批量,耐手焊 |
| SOP-8(150 mil) | 约 4.9 × 3.9 mm | 1.27 mm | 最主流,手焊返修友好,样机首选 |
| SOP-8(208 mil) | 约 5.3 × 5.2 mm | 1.27 mm | 老型号,面积大 |
| TSSOP-8 | 3.0 × 4.4 mm(厚 1.0 mm) | 0.65 mm | 薄型,占板小,适合紧凑设计 |
| MSOP-8 / VSSOP-8 | 3.0 × 3.0 mm | 0.65 mm | 更薄更小,需精细 SMT |
| DFN-8 / UDFN-8 | 2 × 3 mm / 3 × 3 mm | 0.5 mm | 无引线,底部焊盘,穿戴 / 手机模组 |
| SOT-23-5 / TSOT-5 | 2.9 × 1.6 mm | 0.95 mm | 1 Kb ~ 16 Kb 小容量,引脚极少 |
| WLCSP-4 / 5 / 8 | 1.0 ~ 2.0 mm 见方 | 0.4 ~ 0.5 mm 球距 | 最小方案,无地址脚,需底部填充(underfill) |
| 28 脚 SOP / TSOP / PLCC-32 | 因厂商而异 | 1.27 / 0.55 mm | 并行 28C64 / 28C256,老设备替代 |
1.3 关键电气参数
| 参数 | 典型范围 | 说明与设计影响 |
|---|---|---|
| VCC — 宽压系列 (24AA / 24LCxxB、25AAxx) | 1.7 ~ 5.5 V | 首选。可同时兼容 1.8 V / 3.3 V / 5 V 系统,电池供电直接接 |
| VCC — 2.5 V 系 | 2.5 ~ 5.5 V | 老型号常见,1.8 V 系统不可用 |
| VCC — 5 V 系(24Cxx 老型号) | 4.5 ~ 5.5 V | 仅 5 V 系统,替换时注意 |
| VCC — 1.8 V 系 | 1.6 ~ 3.6 V | 低压低功耗型号 |
| VIH / VIL | ≥ 0.7 × VCC / ≤ 0.3 × VCC | 部分低压型号为 0.7 / 0.2 × VCC;混合电压系统需电平转换 |
| VOL(max) @ IOL | 0.4 V @ 3 mA (VCC < 2.5 V 时 0.2 × VCC) | 上拉电阻 Rp(min) 计算的依据,见 5.1 |
| IOL(SDA 低电平灌电流) | 3 mA(标准/FM) 6 ~ 20 mA(FM+) | FM+ 器件可用更小上拉,见 5.1 |
| 输入漏电 IIL / IOL(leak) | ±1 µA(typ)/ ±3 µA(max) | 总线挂 8 个器件时累计漏电 ≤ 24 µA,影响上拉取值 |
| 引脚电容 CI/O | ≤ 10 pF(I²C 规范上限) 典型 6 ~ 8 pF | 总线电容预算的核心参数,见 5.3 |
| I²C 速率档 | 100 kHz(Standard) 400 kHz(Fast) 1 MHz(Fast-mode Plus) | 1 MHz 需器件与主控均支持 FM+;400 kHz 通常在全压段可用,1 MHz 可能要求 VCC ≥ 2.5 V |
| SPI 速率 | 1 / 2 / 3 / 5 / 10 / 20 MHz | 25AA 常见 10 MHz @5 V、5 MHz @3.3 V、1 MHz @1.8 V,低压降频 |
| SPI 模式 | Mode 0(CPOL=0,CPHA=0) Mode 3(CPOL=1,CPHA=1) | 多数 25xx 两者都支持;配置错误表现为数据整体位移 1 bit |
| 页大小(Page Size) | 8 / 16 / 32 / 64 / 128 / 256 B | 随容量变化,见 1.4;页写不可跨页 |
| 写周期 tWR / tWC | typ 5 ms,max 10 ms (部分高速型号 3 ms) | 写 1 字节与写 1 页相同。超时判定必须按 max;用 ACK 轮询可提前结束 |
| 擦写耐久 endurance | 10⁶ 次 / 字节 部分型号 4 × 10⁶ | 按字节计(24Cxx),非按页;高温下 endurance 通常更高、保持期更短 |
| 数据保持 | 100 年 @25 °C (部分标 40 / 200 年) | Arrhenius 加速:85 °C 下显著缩短(如 100 年 → 数十年,按型号曲线) |
| 读电流 ICC(read) | 0.4 ~ 1 mA @400 kHz 2 mA @1 MHz | 与速率近似线性 |
| 写电流 ICC(write) | 2 ~ 3 mA @5 V 1 ~ 2 mA @3.3 V | 内部电荷泵工作,持续整个 tWR;是电源跌落设计的输入条件 |
| 待机电流 ISB | 1 ~ 5 µA @5.5 V < 1 µA @1.8 V | 决定电池备份寿命(见 3.5) |
| 上电到首次访问 tPOR / tPU | 建议等待 ≥ 10 ms (部分型号规定 max 10 ms) | VCC 越过 VCC(min) 后需延时再发 START |
| 总线释放时间 tBUF | 4.7 µs(100 kHz) 1.3 µs(400 kHz) | STOP 到下一个 START 的最小间隔 |
| 工作温度 | -40 ~ +85 °C(工业) -40 ~ +125 °C(车规 / 部分工业) | 高温段注意速率降额与保持期缩短 |
| 存储温度 | -65 ~ +150 °C | 仅指未上电存储 |
| ESD 等级 | HBM 4 kV(部分 2 kV) CDM 1 kV / MM 200 V | 见第 8 章;SDA/SCL 直连连接器时必须加 TVS |
几乎所有 EEPROM 相关的工程问题都源于 tWR = 5 ms 这个数字:写入吞吐上限(字节写串行 ≈ 200 B/s @页 8 B)、掉电保护窗口(必须撑住 ≥ 10 ms)、写期间总线不可用(ACK 轮询)、频繁改写寿命(10⁶ 次)。
反过来,tWR 也决定了 EEPROM 只适合"低频次、小批量、高可靠"的参数存储,不适合数据流记录。
1.4 容量、页大小与地址结构
这是 EEPROM 硬件设计里最容易出错的一节:页大小、地址字节数、可用地址引脚数,全部随容量变化。同一块 PCB 上把 24C02 换成 24C04,可能直接导致总线地址冲突。
| 型号 | 容量 (bit) | 容量 (Byte) | 页大小 (B) | 内部地址 字宽度 | 有效地址 引脚 | 同总线 最大器件数 | 说明 |
|---|---|---|---|---|---|---|---|
| 24C01 | 1 Kb | 128 | 8 | 1 字节 | A2 A1 A0 | 8 | 小容量,逐步被 24C02 取代 |
| 24C02 | 2 Kb | 256 | 8 | 1 字节 | A2 A1 A0 | 8 | 最常用;页仅 8 B,写 32 B 需 4 次页写 |
| 24C04 | 4 Kb | 512 | 16 | 1 字节 + P0 | A2 A1(A0→P0) | 4 | A0 脚失效,改作页地址 P0,接到器件地址位 0 |
| 24C08 | 8 Kb | 1 K | 16 | 1 字节 + P1P0 | A2(A1A0→P1P0) | 2 | 两个页地址位 |
| 24C16 | 16 Kb | 2 K | 16 | 1 字节 + P2P1P0 | 无 | 1 | 三个地址脚全失效,一条总线只能挂 1 颗 |
| 24C32 | 32 Kb | 4 K | 32 | 2 字节 | A2 A1 A0 | 8 | 地址字恢复 2 字节,地址脚全部有效 |
| 24C64 | 64 Kb | 8 K | 32 | 2 字节 | A2 A1 A0 | 8 | FRAM FM24CL64 引脚兼容替代对象 |
| 24C128 | 128 Kb | 16 K | 64 | 2 字节 | A2 A1 A0 | 8 | 地址脚全部有效,最多 8 颗,与 24C32/64/512 一致 |
| 24C256 | 256 Kb | 32 K | 64 | 2 字节 | A2 A1 A0 | 8 | 地址脚全部有效,最多 8 颗,与 24C32/64/512 一致 |
| 24C512 | 512 Kb | 64 K | 128 | 2 字节 | A2 A1 A0 | 8 | 地址脚恢复全有效 |
| 24C1024 | 1 Mb | 128 K | 256 | 2 字节 + B0 | A2 A1(A0→B0/NC) | 4 | A0 多作块选择 B0 或 NC,以手册为准 |
| 24CM02 | 2 Mb | 256 K | 256 | 2 字节 + B0 | A2 A1(A0→B0/NC) | 4 | 容量上限,成本较高 |
24C04/08/16 为了在 8 位地址字的 256 字节寻址能力之上扩展容量,把器件地址字节中原本属于 A2A1A0 的位借用为内部页地址 P0/P1/P2。后果:
· 24C04 只有 A2/A1 两个有效地址脚(A0 被改作内存块位 P0,每颗占 2 个 7 位地址)→ 同总线最多 4 颗,写基地址(P0=0)分别为 0xA0 / 0xA4 / 0xA8 / 0xAC(每颗另含 P0=1 的 0xA2 / 0xA6 / 0xAA / 0xAE);
· 24C08 只有 A2 一个有效地址脚(A1/A0 被改作内存块位 P1/P0,每颗占 8 个地址)→ 同总线 2 颗(写地址块 0xA0~0xA7 与 0xA8~0xAF);
· 24C16 → 同总线 1 颗,A2A1A0 必须全部接地(或按手册悬空),此时器件占掉 0xA0 ~ 0xAF 全部 16 个地址,再挂任何 24Cxx 都会冲突。
设计规则:先用容量表确认可挂器件数,再画原理图;24C16 与 24C02 不能在同一条 I²C 总线上共存。
一次页写操作可以连续写入最多 1 页(24C02 为 8 B,24C64 为 32 B)。内部地址计数器只在页内的低位自动递增,高位保持不变。
举例:24C02(页 8 B)从地址 0x05 开始连续写 8 个字节,正确预期是写入 0x05~0x0C;实际结果是:
· 0x05、0x06、0x07 正常写入;
· 第 4 个字节回卷到 0x00,第 5 个到 0x01,……,第 8 个写到 0x03;
· 器件不报错、ACK 正常返回,数据被静默覆盖。
规避规则:驱动层必须按页边界切分写操作(见 2.2 的 eeprom_write() 参考实现)。这是 EEPROM 量产事故的第一大来源。
器件地址的 7 位 / 8 位表示
I²C 器件地址本身是 7 位。对 24Cxx 而言固定高 4 位为 1010:
7 位地址 = 1 0 1 0 A2 A1 A0 → 24C02 且 A2A1A0 = 000 时,7 位地址 = 0x50
8 位写地址 = (7位地址 << 1) | 0 → 0xA0
8 位读地址 = (7位地址 << 1) | 1 → 0xA1
常见误区:把 0xA0 当成"7 位地址"填进 MCU 的 I2C->OAR / 地址寄存器。
多数 MCU 的 HAL 要求填 7 位地址(0x50),驱动内部再左移;
也有部分驱动要求直接填 8 位(0xA0)。填错表现为"地址整体偏移一位",
现象是扫描时器件出现在 0x28 / 0xA0 等意外位置。
| 器件 | A2 A1 A0 | 7 位地址 | 写地址(8 位) | 读地址(8 位) |
|---|---|---|---|---|
| 24C02 #0 | 0 0 0 | 0x50 | 0xA0 | 0xA1 |
| 24C02 #1 | 0 0 1 | 0x51 | 0xA2 | 0xA3 |
| 24C02 #2 | 0 1 0 | 0x52 | 0xA4 | 0xA5 |
| 24C02 #3 | 0 1 1 | 0x53 | 0xA6 | 0xA7 |
| 24C02 #4 | 1 0 0 | 0x54 | 0xA8 | 0xA9 |
| 24C02 #5 | 1 0 1 | 0x55 | 0xAA | 0xAB |
| 24C02 #6 | 1 1 0 | 0x56 | 0xAC | 0xAD |
| 24C02 #7 | 1 1 1 | 0x57 | 0xAE | 0xAF |
2 · 接口与协议
2.1 I²C 总线基础与器件地址
I²C 是两线、开漏(open-drain)、线与(wired-AND)的同步串行总线:SCL 由主机产生,SDA 双向。所有器件只能把总线拉低或释放,高电平完全由上拉电阻提供——这就是第 5 章上拉电阻计算如此关键的原因。
控制字节(Control Byte)格式
bit: 7 6 5 4 3 2 1 0
┌────┬────┬────┬────┬────┬────┬────┬────┐
│ 1 │ 0 │ 1 │ 0 │ A2 │ A1 │ A0 │ R/W│
└────┴────┴────┴────┴────┴────┴────┴────┘
└─── 器件类型码 1010(EEPROM 固定)───┘ └─ 1=读 / 0=写
24C02 且 A2A1A0=000:写 = 0xA0 读 = 0xA1 (7 位地址 = 0x50)
24C16(无地址脚) :占用 0xA0 ~ 0xAF 全部 16 个 8 位地址
24C04(A0→P0) :P0 占据 bit1 位置,A2/A1 在 bit3/bit2
24C08(A1A0→P1P0):P1P0 占据 bit2/bit1,A2 在 bit3
内部地址字(Word Address)
| 容量段 | 地址字宽度 | 发送顺序 | 说明 |
|---|---|---|---|
| 24C01 ~ 24C16 | 8 bit(1 字节) | 单字节 | 寻址 0x00 ~ 0xFF,超出部分由控制字节中的 P0/P1/P2 覆盖 |
| 24C32 ~ 24CM02 | 16 bit(2 字节) | 先高字节、后低字节 | 每个字节后都有一个 ACK 位;顺序颠倒是最常见的驱动 Bug |
I²C 允许从机在收到一个字节后把 SCL 继续拉低,迫主机等待。部分 EEPROM 支持时钟延展(内部处理慢时拉低 SCL),主机须容忍;同一总线上若有 RTC、传感器、显示驱动等器件,主机 I²C 外设必须支持时钟延展,否则会出现"偶发丢字节"。
用 GPIO 模拟 I²C(bit-bang)时,SCL 必须配置为开漏(或"写 0 / 释放"模式)并在读回时检测 SCL 实际电平再拉高,否则会与延展的从机硬碰硬。
2.2 I²C 写操作与 ACK 轮询
字节写(Byte Write)
- 主机发 START;
- 发控制字节(
1010 A2A1A0 0),器件回 ACK; - 发内部地址字(1 或 2 字节,每字节后 ACK);
- 发 1 个数据字节,器件回 ACK;
- 主机发 STOP → 器件启动内部写周期 tWR;
- tWR 期间器件不响应任何总线访问(对寻址返回 NACK)。
页写(Page Write)与回卷
页写把第 4 步的单个数据字节扩展为连续 N 个字节(N ≤ 页大小),每字节后都有 ACK,最后 STOP 后一次性进入 tWR。只在页内地址低位递增,高位锁存——因此绝不能跨页。
ACK 轮询(Acknowledge Polling)
写周期结束前器件对所有寻址返回 NACK。因此可以用"反复发送写控制字节并检测 ACK"来判断写完成,比死等 10 ms 快得多(实测典型 3 ~ 5 ms 即完成),在高吞吐写入场景下收益明显。
/* 等待 EEPROM 内部写周期结束(ACK 轮询),返回 0=就绪 1=超时 */
uint8_t eeprom_wait_ready(uint8_t dev7, uint32_t timeout_ms)
{
uint32_t t0 = millis();
while ((uint32_t)(millis() - t0) < timeout_ms) {
i2c_start();
if (i2c_write_byte((dev7 << 1) | 0) == ACK) { /* 收到 ACK = 写周期已结束 */
i2c_stop();
return 0;
}
i2c_stop();
delay_us(200); /* 轮询间隔 100 ~ 500 µs,不宜过密 */
}
return 1; /* 超时:可能是器件损坏、总线挂死或 WP 一直有效 */
}
① 轮询必须用写地址(R/W=0)。用读地址轮询通常也能工作,但会在总线上产生一次空读,某些器件会因此把内部地址计数器推进一格,影响后续"当前地址读"。
② 轮询时每次都要发完整的 START + 控制字节 + STOP,不能只发 START。且两次尝试之间建议留 100 ~ 500 µs 间隔,避免总线被 100% 占用导致同总线其它器件(如 RTC 秒更新)被饿死。
带页边界切分的写函数(推荐实现)
/* 通用 EEPROM 写:自动按页切分 + ACK 轮询,规避页写回卷 */
#define PAGE_SIZE 32u /* 24C64 = 32 B;24C02 = 8 B;按 1.4 表取值 */
#define DEV_ADDR 0x50u /* 7 位地址,A2A1A0 = 000 */
int eeprom_write(uint16_t addr, const uint8_t *buf, uint16_t len)
{
uint16_t idx = 0;
while (idx < len) {
/* 1) 计算本页剩余字节数:页边界对齐 */
uint16_t page_off = addr & (PAGE_SIZE - 1); /* 页内偏移 */
uint16_t chunk = PAGE_SIZE - page_off; /* 本页可写字节数 */
if (chunk > (len - idx)) chunk = len - idx;
/* 2) 一帧页写 */
if (eeprom_wait_ready(DEV_ADDR, 20)) return -1; /* 等上次写完成 */
i2c_start();
i2c_write_byte((DEV_ADDR << 1) | 0); /* 写控制字节 */
i2c_write_byte((uint8_t)(addr >> 8)); /* 地址高字节(≥32Kb 时)*/
i2c_write_byte((uint8_t)(addr & 0xFF)); /* 地址低字节 */
for (uint16_t i = 0; i < chunk; i++)
i2c_write_byte(buf[idx + i]);
i2c_stop(); /* STOP 后启动 tWR */
addr += chunk; idx += chunk;
}
return eeprom_wait_ready(DEV_ADDR, 20) ? -2 : 0;
}
从地址 0x05 起连续写 8 字节 11 22 33 44 55 66 77 88:
预期:0x05~0x0C = 11 22 33 44 55 66 77 88(跨到第二页)
实际:0x05 = 11、0x06 = 22、0x07 = 33,然后 0x00 = 44、0x01 = 55、0x02 = 66、0x03 = 77、0x04 = 88
——原 0x00~0x04 的内容被静默覆盖,且器件 ACK 正常、无报错。唯一可靠的规避手段就是上面的驱动层分页。
2.3 I²C 读操作
| 模式 | 帧结构 | 用途 | 注意事项 |
|---|---|---|---|
| 当前地址读 Current Address Read | S → 器件地址+R → A → 数据 → NACK → P | 连续读取上一次操作后的下一字节 | 依赖内部地址计数器,上电后为 0;只在"刚写完/刚读完"的场景用 |
| 随机读 Random Read | S → 器件地址+W → A → 字地址 → A → Sr(重复 START) → 器件地址+R → A → 数据 → NACK → P | 读任意地址,最常用 | 前半段是"伪写(dummy write)",只装载地址指针,不发 STOP;中间必须是重复 START |
| 顺序读 Sequential Read | 随机读起始 → 数据 → ACK → 数据 → ACK … → 最后字节 NACK → P | 连续读大块数据 | 主机对最后一字节必须回 NACK 再 STOP,否则器件会继续驱动 SDA;地址计数器到达容量上限后回卷到 0x0000 |
/* 随机读 + 顺序读:addr → buf,共 len 字节 */
int eeprom_read(uint16_t addr, uint8_t *buf, uint16_t len)
{
if (eeprom_wait_ready(DEV_ADDR, 20)) return -1; /* 读之前也要等上一次写完成 */
i2c_start();
i2c_write_byte((DEV_ADDR << 1) | 0); /* 伪写:器件地址 + W */
i2c_write_byte((uint8_t)(addr >> 8));
i2c_write_byte((uint8_t)(addr & 0xFF));
i2c_start(); /* 重复 START(不得先 STOP)*/
i2c_write_byte((DEV_ADDR << 1) | 1); /* 器件地址 + R */
for (uint16_t i = 0; i < len; i++) {
buf[i] = i2c_read_byte(i == (len - 1) ? NACK : ACK);
}
i2c_stop(); /* 读操作没有 tWR,可立即继续访问 */
return 0;
}
读本身不消耗 tWR,可以背靠背连续读。但紧跟在写操作之后的读必须先等 tWR 结束(即 ACK 轮询通过),否则第一帧就 NACK。eeprom_read() 开头那句 eeprom_wait_ready() 不能省。
24Cxx 的 WP 引脚为高电平写保护(多数型号)。被保护时:
· 写控制字节后器件仍会返回 ACK(地址匹配),但随后的数据字节被忽略,内部写周期不启动;
· 用一个"写保护中"的器件做 ACK 轮询会立即返回 ACK 而误判为写完成——这是"写进去读出来还是旧值"的经典成因之一;
· 读操作不受 WP 影响。
排查建议:写函数返回前回读校验;若回读失败,先量 WP 引脚电平。
2.4 SPI EEPROM(25AA / 25LC 系列)
SPI EEPROM 与 I²C EEPROM 的存储器阵列几乎相同(同样的 tWR、endurance、保持期),差别只在接口:SPI 为四线推挽(CS#/SCK/SI/SO)+ 两个控制脚(WP#/HOLD#),速率更高、无总线电容限制、无地址冲突问题,代价是多占 2~4 个 MCU 引脚。
指令集
| 指令 | 操作码 | 功能 | 说明 |
|---|---|---|---|
| READ | 0x03 | 从指定地址连续读 | 地址自动递增,可一次读完整个器件(无页限制);跨到末尾回卷到 0x0000 |
| WRITE | 0x02 | 写入 1 字节至 1 页 | 必须先发 WREN;不可跨页;CS# 拉高后启动 tWC |
| WREN | 0x06 | 置位写使能锁存 WEL | WEL 在写周期结束、WRDI、掉电后自动清零 → 每次写前都要重发 |
| WRDI | 0x04 | 清零 WEL | 写完主动发一次,防止误写 |
| RDSR | 0x05 | 读状态寄存器 | 判断写完成的唯一手段(WIP 位),可连续读(CS# 保持低,SCK 持续翻转) |
| WRSR | 0x01 | 写状态寄存器 | 设置 BP1/BP0 块保护与 WPEN;需先 WREN;受 WP# 引脚约束 |
状态寄存器(Status Register)
bit: 7 6 5 4 3 2 1 0
┌──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┐
│ WPEN │ x │ x │ x │ BP1 │ BP0 │ WEL │ WIP │
└──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘
WIP = 1:写操作进行中(Write In Progress) ← 轮询此位等待写完成
WEL = 1:写使能锁存已置位(Write Enable Latch)
BP1/BP0:块保护(00=无保护 01=高 1/4 10=高 1/2 11=全片) ← 编码因厂商/容量而异
WPEN = 1:WP# 引脚生效(配合 WP#=0 时禁止 WRSR)
注意:部分厂商把 bit0 定义为 nRDY(0=忙 / 1=就绪),极性相反,
移植驱动时务必核对:while(RDSR & 0x01); 与 while(!(RDSR & 0x01)); 差之一位谬以千里。
地址字节数与页大小
| 系列 | 容量 | 地址字节数 | 页大小 | 最高时钟(典型) |
|---|---|---|---|---|
| 25AA010 / 020 / 040 | 1 / 2 / 4 Kb | 1 字节(040 把 A8 编入指令低 3 位) | 16 B | 10 MHz @5 V |
| 25AA080 / 160 / 320 | 8 / 16 / 32 Kb | 2 字节 | 16 / 32 B | 10 MHz @5 V |
| 25AA640 / 128 / 256 | 64 / 128 / 256 Kb | 2 字节 | 32 / 64 B | 10 MHz @5 V、5 MHz @3.3 V |
| 25AA512 / 1024 | 512 Kb / 1 Mb | 2 / 3 字节(24 bit) | 128 / 256 B | 20 MHz(高速型号) |
/* SPI EEPROM 写一页(25AA256,页 64 B)——注意 CS# 每帧必须完整拉高 */
void spi_eeprom_write_page(uint16_t addr, const uint8_t *buf, uint8_t len)
{
uint8_t sr;
CS_LOW(); spi_xfer(0x05); sr = spi_xfer(0xFF); CS_HIGH(); /* RDSR */
while (sr & 0x01) { /* WIP=1 则等待 */
CS_LOW(); spi_xfer(0x05); sr = spi_xfer(0xFF); CS_HIGH();
}
CS_LOW(); spi_xfer(0x06); CS_HIGH(); /* WREN:必须在 CS# 上升沿生效 */
CS_LOW();
spi_xfer(0x02); /* WRITE */
spi_xfer((uint8_t)(addr >> 8)); /* 地址高字节在前 */
spi_xfer((uint8_t)(addr & 0xFF));
for (uint8_t i = 0; i < len; i++)
spi_xfer(buf[i]); /* len ≤ 64 且不跨页 */
CS_HIGH(); /* 上升沿启动内部写周期 tWC ≈ 5 ms */
CS_LOW(); spi_xfer(0x04); CS_HIGH(); /* WRDI(可选,写后 WEL 自动清)*/
}
① 忘记 WREN:WRITE 指令在 WEL=0 时被静默忽略,读回全是旧值。WEL 在每次写周期结束后自动清零,所以每一帧写之前都必须重新发 0x06。
② WREN 与 WRITE 之间拉高了 CS# 又没拉高:WREN 是在 CS# 上升沿锁存的,若把 WREN 和 WRITE 放在同一个 CS# 低电平里连续发送,多数器件不认。必须 WREN 结束拉高 CS#,再拉低发 WRITE。
③ WIP 位极性搞反:华邦 / Microchip 多为 WIP(1=忙),部分国产兼容料为 nRDY(1=就绪)。while(sr & 0x01); 会变成死循环。
HOLD# 的正确用法
HOLD# 在传输中途拉低可以冻结当前指令(器件忽略 SCK,SI/SO 保持),此时主机可把总线让给其它从机,之后拉高 HOLD# 继续。注意:
- HOLD# 只能在 SCK 为低电平时切换,否则当前位可能被破坏;
- HOLD# 期间 CS# 必须保持低电平;
- 单主单从系统基本用不到,但引脚必须上拉(见 1.2 的警告框)。
2.5 Microwire 93xx(93C46 / 56 / 66 / 76 / 86)
Microwire 是三线同步串行接口(CS / SK / DI / DO,DI 与 DO 分开,实为四线半双工),多见于老设计、汽车电子与部分国产 MCU 生态。
| 引脚 | 名称 | 说明 |
|---|---|---|
| 1 | CS | 片选,高有效(与 SPI 相反)。上升沿启动内部写周期 |
| 2 | SK | 串行时钟,最高 1 ~ 3 MHz(依型号与电压) |
| 3 | DI | 串行数据输入(指令、地址、写数据) |
| 4 | DO | 串行数据输出;写操作期间可作 BUSY/RDY# 指示(依型号) |
| 5 | GND | 地 |
| 6 | ORG | 组织选择:接 VCC = 16 位字组织,接地 = 8 位字节组织。严禁悬空,改动会改变整个地址空间 |
| 7 | DC / PE / NC | 依型号:不连接(DC)、写使能(PE)或空脚(NC) |
| 8 | VCC | 电源 |
指令帧格式(以 93C46,ORG=0 即 8 位组织为例)
帧 = 起始位(1) + 操作码(2 bit) + 地址(7 bit) [+ 数据(8 或 16 bit)]
┌───┬───────┬───────────┬─────────────┐
│ 1 │ OP │ A6..A0 │ D7..D0 │
└───┴───────┴───────────┴─────────────┘
READ = 1 10 A6..A0 → DO 输出 8/16 bit(前面有一个前导 0)
EWEN = 1 00 11xxxxx → 写使能(必须先执行)
WRITE = 1 01 A6..A0 + D7..D0 → CS 上升沿后启动 tWC
ERASE = 1 11 A6..A0 → 擦除单个单元
ERAL = 1 00 10xxxxx → 整片擦除
WRAL = 1 00 01xxxxx + D → 整片写同一数据
EWDS = 1 00 00xxxxx → 写禁止(写完建议执行,防误写)
地址位宽随容量变化:93C46 = 7 bit(ORG=0)/ 6 bit(ORG=1)
93C56 = 8 / 7 bit,93C66 = 9 / 8 bit,依此类推
① ORG 脚改变地址空间:同一颗 93C46 在 ORG=0 时是 128 × 8 bit,ORG=1 时是 64 × 16 bit。PCB 上一旦把 ORG 焊错电平,软件按 8 位访问会读到"每隔一个字节"的错位数据。ORG 必须显式上拉或下拉,禁止浮空。
② CS 高有效 + 写使能用 EWEN/EWDS:与 SPI 的 CS# 低有效 + WREN 完全相反,混用会导致"指令发完没反应"。93C46 等部分型号还有 PE(Program Enable) 脚,必须拉高才能写入。
2.6 UNI/O 11xx(单线,11AA / 11LC 系列)
UNI/O 是 Microchip 的单线半双工接口,只需 1 个 MCU 引脚(SCIO),非常适合引脚极端紧张的场合(TWS 耳机、一次性医疗耗材、传感器探头、线缆 e-Marker)。
| 项目 | 参数 | 说明 |
|---|---|---|
| 引脚 | SCIO / VSS / VCC(3 脚 SOT-23 或 2 脚) | 单线双向,需外接上拉电阻(典型 4.7 ~ 10 kΩ 到 VCC,按手册选取) |
| 编码 | 曼彻斯特(Manchester)编码 | 自带时钟,对波特率偏差不敏感 |
| 速率 | 10 ~ 100 kHz(典型上限 100 kHz) | 远慢于 I²C/SPI,单次访问耗时以百 µs 计 |
| 帧结构 | 前导码 0x55 + 器件地址(8/12 bit)+ 指令 + 地址 + 数据 + MAK / NoMAK 应答 | MAK(Master Acknowledge)由主机发出,用来指示"还有后续字节" |
| 主要指令 | 0x03 READ、0x6C WRITE、0x96 WREN、0x91 WRDI、0x05 RDSR、0x01 WRSR、0x67 ERASE、0x6B ERAL、0x41 SETAL | 操作码与 SPI 系列部分相同但语义不同,不可照搬 |
| 典型型号 | 11AA010 / 11AA020 / 11AA040、11LC010 ~ 11LC160、11AA02E48(内含 EUI-48) | 11AA02E48 出厂写入全球唯一 MAC,适合做网口 / 物联网设备身份 |
· SCIO 是开漏 + 上拉结构,上拉电阻同时决定上升沿速度,长线时要减小阻值;
· 单线双向,MCU 需在发送与接收之间切换 IO 方向,切换时序严格(典型几百 ns);
· 因为速率低且要切换方向,通常用 GPIO 模拟而非硬件外设,CPU 占用较高;
· 好处是 1 个引脚 + 3 脚封装,在 WLCSP / 2 引脚器件上甚至可与电源共用走线。
2.7 并行 EEPROM(28C64 / 28C256)
并行 EEPROM 已属维护性/替代性方案,主要用于老设备改板、需要 SRAM 级并行读速度的场合。典型:28C64 = 8 K × 8 bit(28 脚),28C256 = 32 K × 8 bit(28 脚)。
| 信号 | 说明 | 设计要求 |
|---|---|---|
| A0 ~ A14 | 地址总线(28C64 用 A0~A12) | 与 MCU 地址总线直连或经锁存器;走线等长要求宽松(ns 级) |
| I/O0 ~ I/O7 | 双向数据总线 | 需双向缓冲;读/写切换由 OE#/WE# 控制 |
| CE# | 片选,低有效 | 必须 10 kΩ 上拉,防止上电期间误选中 |
| OE# | 输出使能,低有效 | 接 MCU 的 RD#(读信号) |
| WE# | 写使能,低有效 | 接 MCU 的 WR#;上电期间必须为高(上拉),否则会误写 |
| RDY/BUSY# | 写周期忙指示(部分型号) | 建议接到 MCU 输入或中断,避免死等 |
关键时序与软件数据保护(SDP)
/* 28C256 字节写:软件数据保护(Software Data Protection)三步解锁序列 */
write_byte(0x5555, 0xAA); /* ① 0xAA → 地址 0x5555 */
write_byte(0x2AAA, 0x55); /* ② 0x55 → 地址 0x2AAA */
write_byte(0x5555, 0xA0); /* ③ 0xA0 → 地址 0x5555(解锁)*/
write_byte(addr, data); /* ④ 真正的写,之后进入 tWC ≈ 5 ~ 10 ms */
/* 判忙方式二选一: */
/* Data# Polling:读回数据的 I/O7 为"写入值的反码",直到写完成才变回正确值 */
/* Toggle Bit :连续读两次,I/O6 持续翻转表示仍在写,稳定表示完成 */
28C256 支持 64 B 页写,但每一字节之间必须满足 tBLC(页写周期时间,典型 100 ~ 150 µs,最大 200 µs)——即从第一个 WE# 上升沿到最后一个 WE# 上升沿不得超过该值,否则页写失效。用慢速 GPIO 模拟总线时极易超时,必须用硬件总线或关闭中断的高速时序。
2.8 I²C 时序参数汇总
| 参数 | 符号 | Standard 100 kHz | Fast 400 kHz | Fast-mode Plus 1 MHz | 设计影响 |
|---|---|---|---|---|---|
| SCL 时钟频率 | fSCL | 0 ~ 100 kHz | 0 ~ 400 kHz | 0 ~ 1 MHz | 器件与主控须同时支持该档 |
| START 建立时间 | tSU;STA | 4.7 µs | 0.6 µs | 0.26 µs | 重复 START 同样适用 |
| START 保持时间 | tHD;STA | 4.0 µs | 0.6 µs | 0.26 µs | START 后到第一个 SCL 下降沿 |
| SCL 低电平宽度 | tLOW | 4.7 µs | 1.3 µs | 0.5 µs | bit-bang 时序需满足 |
| SCL 高电平宽度 | tHIGH | 4.0 µs | 0.6 µs | 0.26 µs | 同上 |
| 数据建立时间 | tSU;DAT | 250 ns | 100 ns | 50 ns | SDA 变化必须在 SCL 上升前沿完成 |
| 数据保持时间 | tHD;DAT | 0 ns | 0 ns | 0 ns | 部分器件要求 ≥ 300 ns,须查手册 |
| 上升时间(max) | tr | 1000 ns | 300 ns | 120 ns | Rp(max) 计算的输入,见 5.2 |
| 下降时间(max) | tf | 300 ns | 300 ns | 120 ns | 开漏下拉本来很快,一般不构成约束 |
| STOP 建立时间 | tSU;STO | 4.0 µs | 0.6 µs | 0.26 µs | SCL 高到 SDA 上升的时间 |
| 总线空闲时间 | tBUF | 4.7 µs | 1.3 µs | 0.5 µs | STOP 到下一个 START |
| 毛刺抑制宽度 | tSP | — | 0 ~ 50 ns | 0 ~ 50 ns | 器件输入滤波器可抑制的窄脉冲 |
| 总线电容(max) | Cb | 400 pF | 400 pF | 550 pF | 器件数 + 走线 + ESD 器件的总预算 |
| 低电平输出电压 | VOL(max) | 0.4 V @ IOL = 3 mA (VCC < 2.5 V 时为 0.2 × VCC) | Rp(min) 计算的输入,见 5.1 | ||
| EEPROM 写周期 | tWR | typ 5 ms / max 10 ms | 与速率无关,由器件内部电荷泵决定 | ||
把总线从 100 kHz 提到 400 kHz,只把命令与地址开销(约 40 bit)从 400 µs 降到 100 µs,而 tWR 5 ms 纹丝不动。写入吞吐由 tWR 主导:
· 24C02(页 8 B):1 页写(突发)≈ 5.4 ms → 约 1.5 KB/s(页写突发,非逐字节写)
· 24C64(页 32 B):1 页写 ≈ 5.4 ms → 约 5.9 KB/s
· 24C512(页 128 B):1 页写 ≈ 5.6 ms → 约 23 KB/s
结论:需要提高写入吞吐时,优先选大页容量型号,而不是提高总线速率。
3 · 电源设计
3.1 宽压供电与去耦
EEPROM 的平均功耗极低,但写操作期间内部电荷泵会产生持续数毫秒的电流脉冲,电源设计的核心是保证这段时间内 VCC 不跌落。
| 项目 | 推荐做法 | 说明 |
|---|---|---|
| 电压等级选择 | 优先 1.7 ~ 5.5 V 宽压型号(24AAxx、24LCxxB、25AAxx) | 同一颗料可覆盖 1.8 / 3.3 / 5 V 三种平台,简化 BOM 与备料 |
| 与 MCU 共电源域 | EEPROM 的 VCC 与 MCU 的 IO 电源同域 | 不同域时必须加电平转换(见 4.4 / 7.4),否则 VIH 不满足 |
| 去耦电容 C1 | 0.1 µF(100 nF)X7R,0402 或 0603,紧靠 VCC 脚(≤ 3 mm) | 吸收电荷泵瞬态;回流路径最短,地端直接打过孔到地平面 |
| Bulk 电容 C2 | 4.7 ~ 10 µF(X5R/X7R),每个电源域 1 颗 | 与板上其它器件共用即可,无需为 EEPROM 单独配置 |
| 电容耐压 | 3.3 V 系统选 ≥ 10 V 耐压,5 V 系统选 ≥ 16 V | X7R 存在 DC bias 效应:6.3 V / 10 µF 在 5 V 偏置下实际容值可能只剩 30% ~ 40% |
| 电源串阻 | 不建议串电阻;如需滤波可串 1 ~ 10 Ω 或磁珠 | 串阻过大 + 写电流会造成 VCC 跌落,见 3.2 |
| 纹波要求 | VCC 纹波峰峰值 ≤ 100 mV(建议 ≤ 50 mV) | 纹波会影响写阈值判据 |
EEPROM 电流只有毫安级,去耦的目的不是稳压而是给电荷泵提供本地电荷源 + 缩短高频回流路径。因此:
· 0.1 µF 电容必须在 EEPROM 的 VCC 与 GND 之间,走线总长 ≤ 5 mm;
· 电容的地端过孔与 EEPROM 的 GND 脚过孔尽量共用或相邻;
· 不要为了"统一美观"把去耦电容排到板边统一放置——对 EEPROM 影响尚小,但对同总线的高速器件是致命的。
3.2 写操作期间的电压跌落
写周期期间 EEPROM 内部电荷泵工作,电流从待机的 µA 级跳到 1 ~ 3 mA 并持续 整个 tWR(典型 5 ms,最坏 10 ms)。如果电源路径阻抗过大,VCC 会在器件引脚处跌落。
/* 写期间电压跌落估算 */
ΔV_drop = I_write × R_source
I_write = 3 mA(5 V 时典型,取 datasheet max)
R_source = 电源路径等效阻抗(LDO 输出阻抗 + PCB 走线 + 磁珠 + 滤波电阻 + 接插件)
例:R_source = 10 Ω(含磁珠 6 Ω + 走线 2 Ω + LDO 输出阻抗 2 Ω)
ΔV_drop = 3 mA × 10 Ω = 30 mV → 可接受
例:串了 100 Ω 电阻做 RC 滤波
ΔV_drop = 3 mA × 100 Ω = 300 mV → 3.3 V 系统跌到 3.0 V,接近 1.7 V 型
号的余量下限,对 2.5 V 型号已越界
/* 断电瞬间需要的储能电容:C = I × t / ΔV */
I = 3 mA(写电流)+ MCU 及其它负载电流
t = 要求的保持时间(≥ tWR_max = 10 ms,建议留 2 倍余量 = 20 ms)
ΔV = 允许的电压跌落(VCC_nominal − VCC_min)
例:3.3 V 系统,VCC_min = 1.8 V,I_total = 10 mA(EEPROM 3 mA + MCU 7 mA)
ΔV = 1.5 V,t = 20 ms
C = 10 mA × 20 ms / 1.5 V = 133 µF → 选 220 µF(考虑容差与老化)
例:只保 EEPROM(MCU 已复位停止工作),I = 3 mA,t = 10 ms,ΔV = 1.5 V
C = 3 mA × 10 ms / 1.5 V = 20 µF → 选 47 µF
EEPROM 的写操作是先擦除隧道氧化层电荷、再注入新电荷的物理过程。若在 tWR 中途 VCC 跌破器件内部写阈值:
· 目标地址的内容不确定(既不是旧值也不是新值,可能是中间态);
· 更严重的是,部分器件在极端掉电条件下会影响同一页内其它字节;
· 器件不会报错,下次上电读出来的就是脏数据。
因此系统的第一原则是:绝不发起一次"注定无法完成"的写操作。见 3.3 的 VCC 监控与 8.4 的软件冗余。
3.3 欠压保护与 VCC 监控
| 方案 | 实现方式 | 优点 | 局限 / 注意 |
|---|---|---|---|
| 器件内建欠压写禁止 (VCC 监控) | 多数现代 EEPROM 内置电压检测,VCC 低于阈值(典型 1.5 V 或按档位)时禁止启动写周期 | 零成本、零软件 | 只能防止"低压下启动写",不能保证已启动的写能写完 |
| MCU 内部 BOR / PVD | 配置掉电检测中断,触发后立即关闭所有 EEPROM 写操作 | 无额外器件 | 阈值固定、精度一般(±5% ~ ±10%);中断响应有延迟 |
| 外部电压检测 IC | 如 TPS3808 / BD47xx / S-808 系列,检测 3.3 V 跌到 3.0 V 时输出复位/中断 | 阈值精确(±1% ~ ±2%)、可带回差 | 增加 1 颗料 + 1 个 MCU 输入 |
| 硬件 WP 联动 | 把电压检测输出同时接到 EEPROM 的 WP 脚(经反相器/三极管按需) | 即使软件跑飞也不会写坏 | WP 极性与检测输出电平要匹配(I²C 型 WP 高有效) |
| 储能电容 + 二极管 | VCC 经肖特基二极管给 100 ~ 470 µF 电容充电,掉电时二极管反偏,电容只供 EEPROM 与 MCU 的最小系统 | 最简单可靠,覆盖 tWR | 占用面积;二极管压降 0.3 V 需在 VCC 预算内扣除 |
| 超级电容 / 电池后备 | 0.1 ~ 1 F 超级电容或纽扣电池,经理想二极管切换 | 可撑数十毫秒到数秒,足够保存大块数据 | 成本高、需充电管理;电池有寿命 |
① 发起写之前必须确认 VCC ≥ VCC(min) + 余量(建议 ≥ 10%)。掉电检测触发后,绝不允许再启动任何新的写操作——这是软件与硬件的联合约束。
② 一次写事务要么完整、要么不发生。掉电保护的正确顺序是:检测到掉电 → 设置"禁止写"标志 → 等待正在进行的写周期结束(不要中途打断)→ 进入安全状态。
③ 不要依赖 WP 引脚做掉电保护。WP 变高只会忽略后续的写数据字节,已经在进行的写周期不会被中止,反而会让你误以为"已经保护了"。
3.4 上电复位与 I²C 总线挂死恢复
上电时序
| 项目 | 典型要求 | 设计处理 |
|---|---|---|
| VCC 上升时间 | 部分型号要求 ≤ 某上限(如 100 ms)或 ≥ 某下限(如 0.1 V/µs) | 大电容 + 高阻电源会造成上升过缓,必要时加电源管理 |
| 上电到首次访问 tPU | 建议 等待 ≥ 10 ms(部分型号规定 max 10 ms) | 初始化流程里加延时,不要用"上电立刻扫描总线" |
| MCU IO 上电态 | 复位期间 IO 为高阻,SCL/SDA 由上拉电阻拉高 → 总线安全 | 若 MCU IO 复位期间为推挽输出低,会把总线拉死,必须选开漏或更换引脚 |
| 多电源域上电顺序 | EEPROM 不应先于 MCU 被访问;允许 EEPROM 与 MCU 同时上电 | 若 EEPROM 由常电(standby)供电而 MCU 后上电,需保证总线在 MCU 未初始化期间被上拉 |
总线挂死(SDA 被永久拉低)与 9 时钟恢复法
典型成因:主机在 EEPROM 正在输出低电平(ACK 或数据 0)时被复位,EEPROM 还在等待剩余的 SCL 脉冲,于是把 SDA 一直拉低,主机再也发不出 START。这是 I²C 系统最常见的"死机"现象。
/* 9 个时钟脉冲恢复法(I²C 规范推荐) */
void i2c_bus_recovery(void)
{
/* 1) 把 SCL 配成 GPIO 推挽输出,SDA 配成输入(带上拉) */
gpio_set_mode(SCL_PIN, OUTPUT_PP);
gpio_set_mode(SDA_PIN, INPUT_PULLUP);
/* 2) 发送 9 个时钟脉冲(或更多,最多 16 个),周期 ≥ 10 µs */
for (int i = 0; i < 9; i++) {
gpio_write(SCL_PIN, 0); delay_us(5);
gpio_write(SCL_PIN, 1); delay_us(5);
if (gpio_read(SDA_PIN) == 1) break; /* SDA 已释放可提前退出 */
}
/* 3) 在 SCL 为高时制造一个 STOP:SDA 由低变高 */
gpio_set_mode(SDA_PIN, OUTPUT_OD);
gpio_write(SDA_PIN, 0); delay_us(5); /* SDA = 0,SCL = 1 */
gpio_write(SDA_PIN, 1); delay_us(5); /* SDA 上升 → STOP 条件 */
/* 4) 引脚交还给 I²C 外设,重新初始化 */
i2c_peripheral_init();
}
/* 硬件兜底:EEPROM VCC 由 MOSFET 控制,软件恢复失败时断电 100 ms 再上电 */
① 主机永远不要在 ACK 位期间复位——软件复位前先发 STOP 并等待 tBUF。
② 若产品允许,给 EEPROM 的 VCC 串一个由 MCU GPIO 控制的 P-MOS 负载开关,作为硬件复位手段(成本约几分钱,能救量产)。
③ 主机 I²C 外设初始化时先做一次总线恢复流程,而不是假设总线干净。
④ EEPROM 写操作期间(tWR)禁止对 MCU 进行在线调试复位;开发阶段尤其容易中招。
3.5 低功耗与电池备份
| 场景 | 电流 / 参数 | 设计要点 |
|---|---|---|
| EEPROM 待机 | 1 ~ 5 µA @5.5 V < 1 µA @1.8 V | 总线空闲(SCL/SDA 均为高)时自动进入待机;不需要专门的休眠指令 |
| 读操作 | 0.4 ~ 2 mA | 缩短访问时间,读完后立即释放总线 |
| 写操作 | 2 ~ 3 mA,持续 5 ms | 单次写能耗 ≈ 3 mA × 5 ms = 15 µC 电荷量 |
| 上拉电阻静态功耗 | 3.3 V / 4.7 kΩ = 0.70 mA(总线为低时) 3.3 V / 10 kΩ = 0.33 mA | 常被忽略:总线低电平期间上拉电阻持续耗电。占空比 50% 时平均 0.35 mA,远大于 EEPROM 自身待机电流 |
| 纽扣电池备份 | CR2032:225 mAh,自放电约 1%/年 | 仅 EEPROM 待机 5 µA → 约 5 年;若加上拉漏电 0.1 mA → 不足 3 个月 |
| 二极管 ORing | 肖特基 Vf ≈ 0.3 V(BAT54) 理想二极管 Vf ≈ 0.02 V | 主电源与电池切换;低压差场景用理想二极管 IC |
· EEPROM 与 MCU 共用备份电源时,MCU 必须进入最低功耗模式,否则 EEPROM 的 µA 级待机毫无意义;
· 上拉电阻接到可被切断的电源域(或改用 MCU IO 内部上拉 + 大阻值),避免备份期间持续漏电;
· 电池备份时建议把 I²C 速率降到 100 kHz 并加大上拉至 10 kΩ,兼顾功耗与可靠性;
· 低压(1.8 V)型号的待机电流明显低于 5 V 型号,电池方案优先选低压宽压料。
4 · 典型应用电路
4.1 I²C 单器件 / 多器件典型电路
逐网络说明(图 4-1)
| 网络 / 位号 | 参数 | 作用与设计说明 |
|---|---|---|
| SCL / SDA | 开漏,2 根信号线 | MCU 侧必须配置为开漏 / 复用开漏;推挽输出会在总线仲裁时造成短路电流 |
| R1 / R2(上拉) | 2.2 kΩ ±5%(400 kHz) 4.7 kΩ(100 kHz) | 全总线只需一组;精确取值见第 5 章计算。上拉必须接到与 EEPROM 相同的电源域 |
| R3(WP 下拉) | 10 kΩ ±5% | 保证 MCU 复位期间 WP = 0(可写)。若要求"默认保护",改为 10 kΩ 上拉到 VCC |
| GPIO_WP | MCU 通用 IO | 软件控制写保护;量产时建议"上电默认保护,需要写时才拉低" |
| C1(去耦) | 100 nF X7R 0402/0603,≥10 V | 每颗 EEPROM 各 1 只,紧靠 VCC 脚,回流路径最短 |
| A0 / A1 / A2 | 0 Ω 电阻或焊盘跳线 | 配置器件地址;严禁悬空。24C04/08/16 上被借用为页地址,见 1.4 |
| VCC | 1.7 ~ 5.5 V(宽压料) | 与 MCU IO 电源同域;不同域需电平转换 |
| J1(板外接口) | 可选 TVS 阵列(结电容 < 10 pF) | 总线引出板外时必须加 ESD 保护;TVS 结电容计入总线电容预算(见 5.3) |
4.2 SPI EEPROM 单器件电路
逐网络说明(图 4-2)
| 网络 / 位号 | 参数 | 作用与设计说明 |
|---|---|---|
| CS# | MCU GPIO 或硬件 NSS,10 kΩ 上拉 | 上拉不可省:保证 MCU 复位期间不被选中。每条指令结束必须拉高,WREN 与 WRITE 之间也要拉高 |
| SCK | 推挽,串 33 Ω | 不上拉;空闲电平由 SPI 模式决定(Mode 0 为低,Mode 3 为高) |
| MOSI → SI | 推挽,串 33 Ω | 主机输出、从机输入 |
| MISO ← SO | 从机三态输出,串 33 Ω | CS# 无效时为高阻,可与其它 SPI 从机共用 MISO |
| WP# | 10 kΩ 上拉 | 低电平保护状态寄存器(配合 WPEN 位)。不用时上拉;需要保护时由 GPIO 拉低 |
| HOLD# | 10 kΩ 上拉 | 必须上拉。单主单从系统一般不使用该功能,但引脚不能浮空 |
| C11 | 100 nF X7R | 紧靠 VCC 脚 |
4.3 多器件共总线
| 场景 | 器件组合 | 可行性 | 处理要点 |
|---|---|---|---|
| 8 × 24C02 | 地址 0x50 ~ 0x57 | 可行 | A2A1A0 全有效,8 个编码全部用满;总线电容 = 8 × 10 pF + 走线 |
| 4 × 24C04 | 0x50~0x51 / 0x52~0x53 / 0x54~0x55 / 0x56~0x57 | 可行 | 仅 A2A1 有效,A0 必须接地 |
| 2 × 24C08 | 0x50~0x53 / 0x54~0x57 | 可行 | 仅 A2 有效 |
| 1 × 24C16 | 独占 0x50 ~ 0x5F | 只能 1 颗 | 与任何 24Cxx 都冲突,需独立总线或 I²C 多路复用器 |
| EEPROM + 传感器 + RTC | 地址互不相同即可 | 可行 | 注意 EEPROM 地址段 0x50~0x57 常与 RTC(0x68)、IO 扩展(0x20~0x27)、温度传感(0x48~0x4B) 冲突,先做全总线地址分配表 |
| 超过 8 颗同型号 | — | 不可行 | 加 I²C 多路复用器(PCA9548,8 通道)或 I²C 缓冲器 + 分段总线,见 5.6 |
原理图画完之后,必须出一张全总线地址分配表并放进设计文档:位号 / 器件型号 / A2A1A0 编码 / 7 位地址 / 8 位写地址 / 8 位读地址 / 备注。
这张表能提前发现 90% 的地址冲突问题,也是量产换料(例如 24C02 换 24C04)时唯一可靠的核对依据。
4.4 电平转换
当 EEPROM 与 MCU 的 IO 电源域不同(典型:MCU 1.8 V,EEPROM 3.3 V;或 EEPROM 由常电 3.3 V 供电而 MCU IO 域会在低功耗时断电),必须做电平转换。I²C 是双向开漏总线,不能用普通的单向电平转换芯片或分压电阻。
| 方案 | 电路 | 适用 | 优缺点 |
|---|---|---|---|
| MOS 管双向转换 | 1 只 N 沟道 MOS(BSS138 / 2N7002)+ 2 只上拉电阻,每根线一套 | 100 ~ 400 kHz,成本敏感 | 成本最低(约 3 分钱/线);速率受 MOS 导通延迟与 Cgs 限制,1 MHz 难达标 |
| 专用双向转换 IC | TXS0102 / TXB0102 / PCA9306 / LSF0102 | 400 kHz ~ 1 MHz | 推荐;集成度高,速率与电容可控(TXS 系列内部有 One-shot,对上拉敏感) |
| I²C 缓冲器 / 中继 | TCA9517 / PCA9517 / P82B715 | 长线 + 不同电平 + 需要隔离电容 | 兼有电平转换与总线驱动能力(见 5.6 / 7.4) |
| 分压电阻 | — | 禁止 | 双向总线上分压会破坏 VOL 电平,且无法反向传输 |
4.5 热插拔与背板应用(EDID / SPD / 摄像头 OTP)
| 应用 | 器件 | 供电 | 关键设计点 |
|---|---|---|---|
| HDMI / DP EDID | 24C02(256 B) | 由主机侧 +5 V 常电经 LDO 转 3.3 V 提供 | · EEPROM 由线缆 / 显示器侧供电,主机侧不供电 · DDC 上拉电阻在主机侧(典型 2.2 kΩ 到 +5 V 或 3.3 V) · SCL/SDA 直接出连接器,必须加 TVS · WP 通常接地(允许主机写入 E-EDID 的部分字段)或上拉(只读) |
| DDR3/DDR4/DDR5 SPD | SPD EEPROM(如 SPD5 Hub 或 24C02 / 34C02) | 内存条上 VDDSPD(2.2 ~ 3.6 V) | · 上拉在主板侧 · 地址固定(0x50 ~ 0x57),由 SA0~SA2 选择 · DDR5 的 SPD5 Hub 内含 I³C/I²C 从机与温度传感 · 热插拔不支持,插拔必须断电 |
| 摄像头模组 OTP | 16 Kb ~ 64 Kb EEPROM(24C16 / 24C64) | 模组内部 2.8 V 或 1.8 V | · 存放 AF 校准、LSC、AWB、模组序列号 · 走 FPC 排线,长度 30 ~ 100 mm,SDA/SCL 与 MIPI 差分对必须分层或保持 3W 间距 · 排线引入 10 ~ 30 pF 电容,需复核总线预算 |
| 可热插拔背板 | 任意 24Cxx | 背板常电 | · 用 PCA9511 / TCA4307 等热插拔缓冲器,带 STOP 检测与总线预充电 · 上拉电阻只放在主机侧,从板侧不加上拉 · 连接器引脚采用长短针(地先接触) |
多板卡系统里最常见的错误是每块板都放一组上拉。N 块板并联后等效上拉 = R/N,可能低于 Rp(min),导致 VOL 超标、器件无法拉低总线。规则:上拉只在主机侧(或总线的一端)放置一组;从板/模组侧不得放上拉。若从板必须自带上拉(如模组出货测试需要),用 0 Ω 或跳线可选断开。