多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

EEPROM 软件设计规范

EEPROM 软件设计规范 编制日期 2026-09-23 版本号 V1.0面向XTX 串行 EEPROMI²C 24Cxx / SPI 25xx 系列的固件驱动设计约定 —— 覆盖ACK 轮询 / WIP 轮询、页写边界回绕、写保护体系、1M 次写 endurance与掉电原子提交逐条给出可落地的命令序列、轮询判据与超时预算。文档编号EEPROM-SW-SPEC-001版本 / 状态V1.0 · 正式发布适用器件XTX 串行 EEPROM 24 系列I²C/ 25 系列SPI容量 1 Kbit ~ 2 Mbit 各档参考标准JEDEC / 厂商 I²C-Compatible Serial EEPROM 与 SPI Serial EEPROM 协议I²C-bus Specification配套文档EEPROM_电路设计指南.html硬件 / 原理图 / 上拉 / 布线约束0. 目的与范围本规范约束 EEPROM 器件在嵌入式固件中的软件行为命令序列、写完成检测ACK / WIP 轮询、页写边界、写保护、endurance 预算与掉电保护。凡本文与器件 datasheet 冲突以 datasheet 为准。统一写完成检测I²C 用ACK 轮询SPI 用RDSR 轮询 WIP绝不靠固定延时替代轮询。统一页写边界规则一次页写不得跨页边界超出部分会回绕到本页首地址覆盖。统一写保护策略WP# 引脚 BP/WPEN 位 块保护组合上电默认状态必须明确。统一掉电保护给出写窗口、提交协议与写入频次预算明确哪些操作是原子的。不在本规范范围硬件原理图与 PCB 布线见《EEPROM 电路设计指南》FRAM / NVSRAM / Microwire / UNI-O / 并行 28Cxx 等特殊接口的算法差异仅作提示 文件系统与磨损均衡算法选型EEPROM 的 endurance 已达百万级通常无需 FTL。一句话结论EEPROM 是「字节可改、页内聚合」的器件 —— 所有写都必须先WRENSPI或起始条件I²C使能再以内部写周期 tWR典型 5 ms落到阵列写完之后器件进入busy状态I²C 不响应 ACKSPI 的 WIP1不轮询完成就继续发命令数据会被静默吞掉。没有坏块、没有 ECC但页边界回绕与写 endurance 累积是它独有的两个坑。文档使用说明本文是《EEPROM 电路设计指南》的软件配套篇硬件篇解决「怎么接、怎么供电、怎么拉上拉」本文解决「驱动怎么写、写完怎么等、错误怎么救」。命令码、寄存器位、时序值均取自典型 I²C 24Cxx 与 SPI 25xx 协议其它厂商/其它密度型号存在差异移植前必须逐条核对。文中 C 代码为协议骨架伪代码演示流程与判断条件非特定平台可直接编译的完整实现i2c_*()、spi_*()、now_ms()等为平台相关底层。贯穿全文的三条铁律①绝不用固定延时替代写完成轮询——tWR 随温度、电压波动且器件 busy 时直接拒绝新命令 ②一次页写绝不跨页边界——超出的字节会回绕覆盖本页开头不会报错 ③超时门限一律取 datasheet max 以上——typ 值只用来安排轮询节奏不能当失败判据。1 · 器件定位与地址组织EEPROM 不是「能改几个字节的 Flash」。它保留了字节可寻址、就地改写的能力但写是以一个内部页为单位聚合提交的——软件设计的第一件事是把「地址空间」「页粒度」和「写完成窗口」搞清楚。1.1 器件定位与关键参数8~256 B页写粒度同一内部写周期最多写入的字节数2 Mbit单片最大容量1 Kbit ~ 2 Mbit 多档24 系列 2 字节地址可达 512 Kbit1,000,000写 endurance每字节/每页 100 万次典型100 年数据保持常温典型高温下缩短5 ms写周期 tWR最大 5 ms部分型号 10 ms期间器件 busy无坏块 / ECCEEPROM 无出厂坏块、无片内 ECC100/400 kHzI²C 时钟标准模式 / 快速模式部分 1 MHz10/20 MHzSPI 时钟25 系列典型最大时钟数据取自典型 I²C 24Cxx 与 SPI 25xx datasheet 的 Features 与 DC/AC 特性章节具体数值随器件型号与厂商不同移植时以对应 datasheet 为准。项目I²C 24Cxx 系列SPI 25xx 系列软件影响接口2 线SDA / SCL4 线CS / SO / SI / SCK底层总线抽象必须分离寻址器件地址 1010 A2A1A0或块地址 R/W字地址 1/2 字节命令字节内嵌 16/24 位字地址I²C 有独立器件地址SPI 靠 CS# 选片写完成检测ACK 轮询busy 时 NACK05h读 SR 的 WIP 位两类驱动路径不同写保护WP# 引脚高整片保护 BP 位部分型号WP# 引脚 SR 的 BP0/1/2 WPENSPI 保护更细I²C 经典器件靠 WP 引脚页大小8 / 16 / 32 / 64 / 128 / 256 B随容量同左页写长度上限必须按型号配置状态寄存器无仅靠 ACK 行为反映 busy有RDSR / WRSRI²C 无法读 SR保护位靠 WP 引脚1.2 容量、页与地址映射EEPROM 的地址是一段连续的字节线性空间软件最容易在这里出错的是「页边界」器件密度总字节数页大小典型字地址宽度页数量1 Kbit128 B1288 B 或 16 B1 字节8 ~ 162 Kbit256 B2568 / 16 B1 字节16 ~ 324 Kbit512 B51216 / 32 B1 字节16 ~ 328 Kbit1 KB102416 / 32 B1 字节32 ~ 6416 Kbit2 KB204816 / 32 B1 字节64 ~ 12832 Kbit4 KB409632 / 64 B2 字节64 ~ 12864 Kbit8 KB819232 / 64 / 128 B2 字节64 ~ 256128 Kbit16 KB~ 2 Mbit16384 ~ 26214464 / 128 / 256 B2 字节大容量 3 字节128 ~ 10241 Device N × 256 B线性字节空间容量从 128 B 到 256 KB2 Mbit无块/页坏块概念1 Page 8 ~ 256 B一次内部写周期最多写入的粒度边界回绕的边界1 Byte 最小读写单位字节可寻址、可随机改写无需擦除即可写写完成窗口 tWR ≈ 5 ms窗口内器件 busyI²C 不 ACKSPI 的 WIP1图 1 · EEPROM 阵列组织字节可寻址、以「页」为单位聚合写入、以 tWR 为单位提交页大小随容量变化绝不能硬编码一个值很多驱动把页大小写死成 32 B移植到 64 B 或 128 B 页的器件后会发生要么每次只写 32 B浪费 tWR、写得很慢要么超过真实页边界造成回绕覆盖。正确做法页大小作为器件表的配置项启动阶段按型号查表或读标识页得到。1.3 与 SPI NOR / NAND 的关键差异移植必读维度SPI NOR / NANDEEPROM移植后果擦除必须先擦除再写NOR 按扇区NAND 按块无需擦除字节可直接改写照搬「先擦后写」会多花无意义操作写完成检测轮询 OIP / 状态位I²C 用 ACK 轮询SPI 用 WIP 轮询NOR 的 05h 轮询在 EEPROM 上含义不同页写边界NOR 按页/扇区NAND 按 cache严格页边界超出回绕覆盖跨边界写被静默吞掉且不报错坏块NOR 无NAND 必有坏块 BBT无坏块EEPROM 不需要坏块管理ECCNAND 必有片内 ECC通常无 ECCEEPROM 读到的就是实际存储值enduranceNOR 10⁵、NAND 6×10⁴ 次10⁶ 次百万级EEPROM 可直接当小参数存储不必上 FTL写保护BP 位 WP#BP 位 WP# WPENSPIWP#I²C 经典I²C 经典器件仅靠 WP 引脚整片保护最容易踩的一条把 NOR 驱动改两行就拿去驱动 EEPROM最常见的死法是写完后用「延时 1 ms」代替轮询EEPROM 的 tWR 是 5 ms 量级1 ms 后器件仍在内部写此时发下一条命令会被忽略或无视——表现为「偶尔丢数据、测多了又正常」。2 · 术语与缩写本章统一术语口径避免「页/块/sector/word address」在文档与代码里指的不是同一件事。2.1 结构与命令术语缩写 / 术语全称本文中的含义Word Address字地址EEPROM 内部字节的线性地址1/2/3 字节即数据在阵列中的位置Page页一次内部写周期tWR所能写入的最大字节数是边界回绕的边界tWRWrite Cycle Time内部写周期时间典型 5 ms / 最大 5~10 ms窗口内器件 busyACK / NACKAcknowledge / Not AcknowledgeI²C 应答位EEPROM busy 时在第 9 个时钟返回 NACKWREN / WRDIWrite Enable / DisableSPI06h / 04h置位/清零 WEL 锁存RDSR / WRSRRead / Write Status RegisterSPI05h / 01hWIPWrite In ProgressSPI 状态位 bit01 内部写进行中0 就绪WELWrite Enable LatchSPI 状态位 bit1写操作前必须先置位BP0/1/2Block Protect bits保护阵列的上 1/4、1/2、全部等区段的组合位WPENWrite Protect EnableSPI 状态位 bit7为 1 时 WP# 引脚才生效WP#Write Protect pin硬件写保护引脚拉高I²C 经典器件或配合 WPENSPI锁保护Endurance耐久度同一字节/页可承受的擦写次数典型 1,000,000 次Retention数据保持断电后数据可保存年限典型 100 年常温2.2 本文书写约定命令码用小写十六进制带后缀h书写如06h、05h与 datasheet 保持一致。状态位写作SR[0]形式方括号内为 bit 位序bit0 为最低位。时序符号沿用 datasheettWR写周期、tSU:WPWP 建立、tBUF停止到起始空闲、fSCL / fCLK总线时钟。「典型值 / 最大值」成对给出时软件超时必须按最大值预算。I²C 字节序列用S … P简记SStartPStopSrRepeated Start括号内为字节含 R/W 位[ACK]/[NACK]表示第 9 时钟的应答。代码示例为 C 伪代码省略总线传输底层实现只表达命令序列与判据。3 · 驱动架构与初始化EEPROM 的驱动比 Flash 简单没有坏块映射、没有 ECC 决策层。但 I²C 与 SPI 两套总线要抽象干净否则上层会写满分支。3.1 分层职责层职责禁止做的事应用层业务调用 read/write/ioctl不感知总线类型直接拼 I²C/SPI 命令、直接算字地址边界存储管理层地址越界检查、页写拆分、提交协议、写频次预算绕过保护检查直接下发写命令协议层WREN WRITE 轮询SPISTART 字地址 数据 轮询I²C省略写使能、省略写完成轮询硬件抽象层I²C / SPI 传输、CS# 时序、上拉与时钟在传输中途切换总线频率或改 GPIO 配置3.2 上电初始化流程上电后 EEPROM 处于就绪状态I²C 立即可响应SPI 的 SR 默认 WEL0。但 I²C 总线可能处于「中间字节」状态SPI 的 CS# 需要正确建立。初始化必须按下列顺序执行1. 上电等待 VCC 稳定I²C 需先满足 tBUFSPI 需满足 tPU上电到 CS# 低2. 总线恢复I²C发 9 个时钟脉冲清 SDA若之前总线卡死SDA 被拉低用 GPIO 模拟 9 个 SCL 释放3. 探测器件I²C ACK / SPI RDSRI²C发 S 器件地址[W] 看是否 ACKSPI06h 无关 05h 读 SR4. 读标识 / 容量确定页大小与地址宽度I²C 按器件型号查表SPI 可 RDID0x9F若支持或查表5. 回读保护状态确认 BP / WPEN / WP#SPIRDSR 看保护位I²C确认 WP# 当前电平与期望一致6. 就绪返回设备句柄含页大小 / 容量 / 总线类型此后所有读写都经管理层做边界与保护检查7. 自检可选回读已知区 / CRC 校验镜像验证上次提交标记是否完整发现半写则回滚图 2 · 上电初始化流程I²C 与 SPI 共用骨架差异在步骤 2/3/4/* SPI 25xx 上电初始化返回 0 表示成功 */ int eeprom25_init(struct eeprom_dev *dev) { uint8_t sr; delay_ms(1); /* tPU上电到 CS# 低至少数百 µs留余量 */ spi_cs_low(); spi_cs_high(); /* 确保 CS# 有高→低跳变SPI 从机进入可寻址态 */ if (rdsr(sr) ! 0) return -E_NODEV; /* 05h 应能读到字节 */ dev-page_size dev-cfg-page_size; /* 来自器件表 */ dev-addr_bytes dev-cfg-addr_bytes; /* 回读保护状态确认 BP / WPEN 符合设计I²C 此步检查 WP# 电平 */ if (sr (SR_WPEN | SR_BP_MASK)) dev-protect_state eeprom_read_protect(); return 0; }I²C 上电初始化里最容易漏的两件事① 总线恢复清 SDA。若上次通信在「主机发完地址但 EEPROM 正要回 ACK」时被复位SDA 可能被 EEPROM 拉低主机再发 Start 会被自己踩住——表现为「器件永远 NACKI²C 总线锁死」。必须在初始化时先发 9 个 SCL 脉冲尝试释放 SDA。② 不探测就直写。EEPROM 没有「写不进去就返回错误」的强约束尤其 I²C 仅靠 ACK地址接错或器件没贴都会表现为「写函数返回成功、读出来是 FFh」。初始化阶段务必做一次探测 回读校准。3.3 器件识别与总线探测I²C 地址探测发S 1010 A2A1A0 0 P若收到 ACK 说明该地址上有器件经典 24Cxx 用 A2/A1/A0 引脚区分同总线多片。SPI RDSR 探测对每片拉 CS# 后发05h应能读回一个字节WEL0 时通常为 0x00 或含保护位读不到则器件不在位。容量/页大小确认I²C 按器件型号查表24C02→256 B / 页 8 或 16 B随料号SPI 可试用9FhRDID部分 25xx 支持或直接查器件表。写保护现状读取SPI 读 SR 拿 BP/WPENI²C 经典器件读 WP# 引脚电平确认与「期望的保护策略」一致。什么时候用器件表而不是探测BOM 固定的产品页大小、地址宽度、保护位定义都应写死在器件表里探测只用于「确认在位」。若固件要兼容同一总线上的多种 EEPROM应以器件表为主键、探测为辅避免把「4 KB 器件按 2 KB 地址访问」这类错误。4 · 状态寄存器与锁存体系SPI 25xx 有一张状态寄存器RDSR/WRSRI²C 24Cxx 则没有状态寄存器——它的「busy」完全靠 ACK 行为体现。理解这两套机制就理解了 EEPROM 的写完成检测。4.1 状态寄存器总览SPI 25xxRDSR (05h) / WRSR (01h) —— 8 位状态寄存器WPENb7—b6BP2b5BP1b4BP0b3—b2WELb1WIPb0WIP 1内部写进行中busy 0就绪图 3 · SPI 25xx 状态寄存器位图不同密度 BP 位数量可能为 2~3 个位名称读写上电默认值软件约定bit7WPENR/W经 WRSR0为 1 时WP# 引脚高电平才使能写保护bit5~3BP2 / BP1 / BP0R/W经 WRSR0块保护组合见第 8 章默认 000 无保护bit1WEL只读由 WREN/WRDI 翻转0写操作前必须为 1写完自动清零bit0WIP只读0写完成轮询的唯一判据4.2 WIP / WEL 判读写操作WRITE 后器件进入 busyWIP1内部写完成后 WIP 自动清零。WEL 在每次写入结束后自动清零下次写前必须重新 WREN。/* SPI 25xx读状态寄存器 */ uint8_t eeprom25_rdsr(void) { uint8_t tx 0x05, rx 0; spi_cs_low(); spi_transfer(tx, 1); spi_read(rx, 1); spi_cs_high(); return rx; } /* 写完成轮询WIP 清零即完成 */ int eeprom25_wait_ready(uint32_t timeout_ms) { uint32_t t0 now_ms(); while (eeprom25_rdsr() SR_WIP) { if (now_ms() - t0 timeout_ms) /* 建议 ≥ 10 mstWR max 5~10 ms */ return -E_TIMEOUT; } return 0; }WIP 只说忙不忙写成功与否另看返回SPI 25xx 的写失败被保护表现为写被直接忽略WIP 仍然正常清零不会置任何错误位。也就是说「轮询到 WIP0」只代表「器件闲了」不代表「写进去了」。被保护的写要靠保护位检查提前拦截而不是事后看状态。4.3 写保护位与 WPEN条件受保护区域说明WPEN0默认BP 位仍可通过 WRSR 配置但 WP# 引脚不生效软件可自由改 BP硬件锁不工作WPEN1 且 WP# 高阵列保护由 BP 位决定SR 解锁可改 WPEN/BP允许写且配置可改WPEN1 且 WP# 低阵列保护仍由 BP 位决定但状态寄存器被锁WRSR 被忽略仅锁 SR硬件写保护生效WPEN 是「是否允许 WP# 生效」的总开关不是「是否保护」很多工程师误以为 WPEN1 就直接保护了阵列——其实阵列保护只由 BP 位决定与 WP# 电平无关WP# 低 WPEN1 仅锁状态寄存器防改 BP/WPENWP# 拉高则 SR 解锁。只置 WPEN 不置 BP阵列仍然可写。相反I²C 经典 24Cxx 没有 WPEN/BPWP# 一拉高就是整片保护无需任何寄存器配置。4.4 I²C 24Cxx 的无状态寄存器I²C 24Cxx没有状态寄存器也不提供读状态命令。它的「写入进行中」完全通过 ACK 行为体现写周期tWR内器件把 SDA 拉低对S 器件地址[W]返回NACK第 9 时钟 SDA1写完成后器件释放 SDA再次探测时返回ACKSDA0因此 I²C 的「写完成轮询」就是反复发起始 地址、看 ACK详见第 6.2 节。I²C 写保护极简只有 WP# 引脚经典 24Cxx含绝大多数 24C02/04/08/16/32/64/128/256整片写保护只有一个开关WP# 引脚为高→ 整片只读为低 → 可写。没有 BP 区段、没有 WPEN。软件要保护某段数据要么在硬件上把 WP# 接固定高电平要么在固件里用「数据本身 校验 幂等提交」来兜底。后续章节请下载「芯参谋」查看……篇幅原因, 还有17章· 详见芯参谋→方案设计当前分享仅开放前5章正文。详细资料请在芯参谋客户端中打开完整文档。打开路径解决方案应用市场分析 - 原理方案设计 - EEPROM_软件设计规范 下载芯参谋客户端
返回列表