【知识分享】EEPROM原理及应用
EEPROM是一种电可擦除可编程只读存储器,具有非易失性特点,广泛应用于设备参数存储。其核心基于浮栅晶体管结构,通过电场实现字节级擦写(10万-100万次寿命),相比EPROM无需紫外线擦除,使用更便捷。
一、简介
EEPROM 是一种不用拔掉芯片,直接通过电就能擦掉旧数据并写入新数据,而且断电后数据不会丢失的小容量存储器,常用于存设备设置、参数等少量需要反复修改的信息。
二、发展历史
- 早期可编程存储器的铺垫(1950-1970 年代)
PROM(可编程只读存储器):1956 年左右出现,用户可一次性编程,但无法擦除修改,应用受限。
EPROM(可擦除可编程只读存储器):1971 年由英特尔工程师 Dov Frohman 发明,通过紫外线照射芯片上的石英窗口擦除数据,需取出芯片操作,使用不便。
- EEPROM 的诞生与商业化(1970-1980 年代)
1978 年,贝尔实验室的 Frank Wanlass 和同事首次提出电可擦除的概念,解决了 EPROM 需物理擦除的痛点。
1980 年代,EEPROM 技术逐步成熟,英特尔、美光等公司推出商业化产品,初期容量仅几 Kb,主要用于工业控制和嵌入式系统。
- 技术迭代与应用扩展(1990 年代至今)
随着半导体工艺进步,EEPROM 容量提升至 Mb 级,擦写速度和耐久性优化(如写入次数从 10 万次提升至 100 万次以上)。
目前,EEPROM 广泛应用于物联网传感器、汽车电子、消费电子等领域,成为小容量非易失性存储的核心器件之一。
三、工作原理
3.1 工作原理:浮栅晶体管与电场擦写机制

EEPROM 的核心基于浮栅晶体管(Floating Gate Transistor) 结构,工作原理如下:
1、物理结构与存储单元
浮栅结构:每个存储单元由一个晶体管组成,其栅极被二氧化硅绝缘层包裹,形成 “浮栅”,可存储电荷。
电荷存储:当浮栅中存有电荷时,晶体管阈值电压升高,表征为 “0”;无电荷时为 “1”。
2、编程(写入)过程
通过在控制栅极施加高压(如 12V),使电子通过氧化层注入浮栅,改变阈值电压,完成数据写入。
3、擦除过程
与 EPROM 不同,EEPROM 擦除无需紫外线,而是通过施加反向电场,使浮栅电荷泄放,实现电擦除。
字节级擦除:可单独擦除某个字节,无需擦除整块数据,灵活性高。
4、读取过程
施加正常工作电压(如 3.3V),通过检测晶体管导通状态读取数据,与 RAM 读取类似,但速度较慢。
注:由于12V电压较高,因此在写入一定次数后,会导致隧道氧化层的绝缘效果变差,产生电荷泄露,所以EEPROM存在擦写次数的寿命限制。
3.2 使用特点:小容量、高灵活、低功耗的非易失性存储
以下是 EEPROM 与常见存储芯片(NOR Flash、NAND Flash、ROM、PROM、EPROM、SRAM、DRAM )的区别:
| 特性 | EEPROM | NOR Flash | NAND Flash | ROM | PROM | EPROM | SRAM | DRAM |
|---|---|---|---|---|---|---|---|---|
| 基本类型 | 电可擦除可编程只读存储器 | 闪存(非易失性) | 闪存(非易失性) | 只读存储器(非易失性) | 可编程只读存储器(非易失性) | 可擦除可编程只读存储器(非易失性) | 静态随机存取存储器(易失性) | 动态随机存取存储器(易失性) |
| 擦写方式 | 电擦除,字节级 操作,可单独擦写一个字节 | 电擦除,需按 块(Block) | 擦除(通常 64 - 128KB 等),但可按字节 / 字编程 | 电擦除,按 块(Block) | 擦除(几百 KB 等 ),按 页(Page,4KB - 16KB 等) | 读写 | 生产时工厂烧录,不可擦写(传统 ROM ) | 专用编程器写入,仅 1 次,写入后不可改 |
| 读写速度 | 读写慢(毫秒级,写入、擦除更明显 ) | 读取快(支持芯片内执行 XIP ,CPU 可直接读指令 ),写入慢 | 连续读写快,随机访问慢(需缓存辅助 ) | 读取速度相对较快(因内容固定 ) | 写入慢(仅 1 次写入机会 ),读取速度一般 | 写入慢(需专用编程器、加电压 ),读取速度一般 | 读写 | 极快(纳秒级 ) |
| 存储容量 | 小(几 KB 到几 MB ) | 较小(几 MB 到几百 MB ) | 大(GB 到 TB 级 ) | 一般根据需求定制,早期容量小 | 容量较小,按需定制 | 容量一般不大(如 27C020 为 2M Bits 等 ) | 小(用于高速缓存,几 KB 到几 MB 级 ) | 大(用于主存,GB 级常见 ) |
| 数据保持性 | 断电后数据 长期保存 | 断电后数据 长期保存 | 断电后数据 长期保存 | 断电后数据 长期保存 | 断电后数据 长期保存 | 断电后数据 长期保存 | 断电后数据 丢失 | 断电后数据 丢失(需定时刷新维持 ) |
| 典型应用 | 存储少量、需频繁更新的数据,如设备配置参数、校准数据、蓝牙配对信息等 | 存储程序代码(如 BIOS、Bootloader )、嵌入式系统固件,需快速随机读取且代码直接执行场景 | 大容量数据存储(如 SSD、U 盘、SD 卡、手机存储 ),流式数据(视频、图片等 )读写 | 早期电脑 BIOS(传统 ROM )、大批量生产的固定数据存储(如某些设备出厂参数 ) | 少量需求场景、ROM 量产前验证(如早期定制化小批量数据存储 ) | 早期可更新程序的存储(因擦写麻烦,逐渐被替代 ) | 电脑 CPU 高速缓存、嵌入式系统高速数据缓存 | 电脑、服务器等主存储器,手机、平板等设备内存 |
| 擦写寿命 | 高(擦写次数约 10 万 - 100 万次 ) | 中(擦写次数约 1 万 - 10 万次 ) | 因类型而异(SLC > MLC > TLC > QLC ,约 1 千 - 10 万次等 ) | 无(不可擦写 ) | 无(仅 1 次写入 ) | 擦写次数有限(紫外线擦除有寿命,反复擦写会影响 ) | 理论上无限(只要不掉电,实际有磨损但极长 ) | 理论上无限(需刷新,实际有硬件寿命 ) |
| 成本 | 高(工艺复杂,容量小 ) | 较高(相比 NAND ,容量小、成本高 ) | 低(高密度、大容量,规模量产优势 ) | 低(大批量生产时成本低 ) | 高(相对 ROM ,且写入慢 ) | 较高(需额外擦除设备、操作复杂 ) | 高(制造工艺复杂,容量小 ) | 低(大容量下成本优势,主流主存选择 ) |
| 接口 / 协议 | 常支持 I2C、SPI 等串行协议 | 常支持 SPI、并行等协议 | 常支持 NAND 专用接口、SPI 等,配合控制器(如 SSD 主控 ) | 无特定接口(地址、数据总线直接访问 ,传统架构 ) | 专用编程器接口 | 专用编程器接口 + 紫外线擦除条件 | 地址、数据总线直接访问(与 CPU 等高速交互 ) | 地址、数据总线直接访问(需内存控制器管理刷新 ) |
四、芯片介绍

常用的EEPROM芯片是SOP8的封装,以ATMEL的EEPROM芯片为例,如上图所示,其中A0、A1、A2三个引脚决定芯片的地址,VCC和GND是一组电源,WP是写保护引脚,SCL是时钟线,SDA是数据线。具体一些细节可以去看官方手册,这里不细讲,这里以24C02这个型号的资料为例,主要讲几个需要重点关注的点。
4.1 供电电压

虽然规格书标称该芯片可以供2.7~5V,但实际供不同电压,参数是有不一样的变化的,像ATMEL的更多是电流上的差异,但有些芯片规格会标明,不同的供电电压,可通信的最大速率是不一样的,EEPROM写周期也是跟随供电电压的变化而变化的。正常来讲,供电电压越低,所用电流越小,支持的最大速率越慢,写周期越长。
4.2 通信速率与写周期时间

因为大部分人使用EEPROM都是用的模拟IIC,而自己实现的模拟IIC很多时候都是用IO口翻转+死循环延时来实现,那么这种写法,其通信速率就由死循环延时的时间决定的。并且使用死循环作为延时,有个很大的缺陷,就是通用性很差,每切换一个单片机平台,都得重新测一下延时,如果你在一个低速的平台实现了一个400kHz的IIC通信,移植到高速平台后,可能会发现读写EEPROM变得不正常,需要重新测试调整延时时间才可以正常使用。
而写周期则算是EEPROM芯片的一个特性,即当你使用IIC通信发送一帧写数据的指令,EEPROM接收到写指令之后,芯片内部开始对数据进行存储,存储的时间长度根据写入的数据不同而不同,所以规格书这里标的是一个最长的时间。在这个写周期内,EEPROM芯片是不响应IIC指令的,所以如果写入后未延时立即进行读取,则读取的数据不是正常想要的值;如果写入后未延时立即进行再次写入,则会出现未应答的情况。
4.3 时序

需要关注这里面各个时间间隔,尤其是使用模拟IIC进行通信时,需要关注模拟的IO口翻转,时序是否满足规格书中的要求。
- 写入

写入时序如上图9,首先发送起始位,然后发送设备地址(具体设备地址是多少下文有讲解),设备地址最后一位为0表示写入,等待EEPROM应答后,再发送需要写入的EEPROM内存起始地址,等待应答后,就开始发送数据,每个字节数据发送完成后,都需要等待应答。单个字节写入与多字节写入的方式是一样的,只是带的数据量不同而已,发送结束后,再发送一个停止信号作为一帧数据的结束。

EEPROM是有页的概念的,正常页写的操作是,写入需要写的起始地址,然后发送数据,发送完一个字节数据后不要发停止信号,而是继续发送数据,直到一页结束。但如果到一页结束后还继续发送数据,则数据会循环覆盖至前面的地址,即上图所说的字节址会"roll over" 。如上面文档所示,1K/2K的,一页是8字节;4K/8K/16K的,一页是16字节。
- 读取

读取时序如上图11,首先发送起始位,然后发送设备地址(具体设备地址是多少下文有讲解),设备地址最后一位为0表示写入,等待EEPROM应答后,再发送需要写入的EEPROM内存起始地址,等待应答后,重新发送起始信号,再发送设备地址,设备地址最后一位为1表示读取,等待EEPROM应答后,就可以正常读取数据。这里其实可以拆成两段来看,第一段就是写入需要操作的内存地址;第二段就是开始读取数据。所以图12表示的是,即使没有第一段写入内存地址,直接进行读操作也是可以的,只是读取的内存地址是从最后一次操作的地址开始。
4.4 设备地址

如上图所示,跟EEPROM通信时,IIC的设备地址由这几部分组成,高4个位为固定的1010,然后再拼接A0~A2这三个位,这三个位的逻辑电平由芯片引脚物理接线方式决定的,最后一位决定是读还是写(1是读,0是写),如果需要逻辑电平1,则外部接Vcc,如果需要逻辑电平0,则外部接GND。比如现在芯片引脚A0接GND,A1和A2接Vcc,那么读该芯片的地址就是0xAD(0b 1010 1101),写地址就是0xAC(0b 1010 1100)。

需要注意的是,这里规格书里提到了,当使用4k的EEPROM时,A0则不起作用;使用8k的EEPROM时,A0和A1都不起作用;使用16k的EEPROM时,则A0、A1、A2均不起作用。
4.5 写保护
芯片的WP引脚为写保护引脚,接GND表示可正常读写,接Vcc时表示只能读,不可写,所以在硬件设计初期,最好是接到一个IO口上,并且需要上拉,防止误写入。
4.6 读写地址
不同大小的EEPROM芯片读写地址的字节数也不一样,因为1个字节能表示的最大值为255,也就是最多可表示256个地址,所以对于2K(bit)以下的EEPROM芯片,只需要使用1个字节,就可以表示256个字节的所有内存地址。对于2K以上的EEPROM芯片,则需要使用2个字节来表示地址。
五、失效预防
为什么会多这么一个章节?是因为这么多年来,被这么一个小小的存储芯片坑了无数遍。为了避免大家重复地掉坑,这里来个大合集,以下全是干货,注意收藏。
5.1 寿命
第一个比较简单,但也算是很多新手的初见杀,就是对于一些没接触过存储芯片的,可能不清楚存储芯片普遍都存在一个标称的擦写寿命,毕竟消费类的产品,比如U盘、电脑硬盘,都很少有存储寿命用尽的,像操作系统还有读写均衡,即使写坏也是无感的。但像嵌入式,很多时候是直接操作这种存储芯片的,那存储芯片最大的一个特性寿命就成了我们必须关注的一个点。
这里需要关注的事情有两个,一个是我们自己使用EEPROM,也就是存储自己的数据时,要注意写入的周期及频次,即使是同一个地址写入同一个数据,也会减少EEPROM的写入寿命,所以对于没有变化的数据,尽量不要去重复写入;对于变化的数据,比如温度、时间这种,则需要根据读写次数去反推,按一定的周期进行存储,或者触发式存储。比如100万次寿命,如果产品需要保证10年的使用年限,那么写入的间隔最短可以是10 * 365 * 24 * 60 / 1000000 = 5.256 min,也就是每间隔5min写入一次数据,大概10年后就会把一个寿命100万次擦写的EEPROM写坏。
第二种则是非自己使用的情况,这里可能有人会问,一般除了嵌入式开发工程师,还有谁能直接去操作EEPROM?是没有人能直接操作,但要留意,我们做产品是给别人用的,那么肯定会有一些触发式存储的功能是留给客户用的,就比如开个接口,给客户存储他那边下发的温度;或给客户留个按键,按一次存储一次数据。下发温度这种,由上位机实现,人家可能就给你来个50ms发一次,而且因为温度这种东西,采集精度等因素导致它就有那么一点点波动,那到嵌入式这里,可能判断的是只要是变更就存储,那从原本预估的10年寿命,可能1周就给干没了。针对这种情况,一个是要做好说明,另外一个在前期需求收集时候,最好是跟客户对齐,不该存储的东西不要存储,或约定好存储周期。
- 失效模式
对于不同芯片厂家,其擦写次数超过规格书寿命要求时的失效模式有所不同,具体失效模式可以咨询原厂技术支持,也可以通过实验写坏来测试。目前遇到的写坏后的失效模式有两种,同样重复给一个地址循环写入0x5A和0xA5,直到超过寿命限制的次数(这边测试写入800w次以上才写坏)。有一家损坏后,只是当前字节数据无法保存,不影响其他字节;而另外一家则是除了当前的字节数据无法保存外,相邻的两个字节也出现问题。而根据厂家的说法,芯片被写坏后,原本写入的数据将无法保持,跟当前芯片是否给电没有关系。因为从上面EEPROM的工作原理可以推导出,写坏是因为隧道氧化层被破坏,导致电荷泄漏无法保持,如果氧化层只是轻微损伤,则内部存储的电荷可以保持较长时间,所以短期可能看不出异常;如果氧化层损伤严重,几乎不支持电荷的存储,则在写入数据后立即回读,就能发现异常。
另外,芯片厂家也提供了一个信息,因为EEPROM这种存储结构,其实只是让数据存储时间可以变得很长,但并不是永久存储,因为既然氧化层是支持电荷穿越的,那么正常不加电场的情况下,实际也是存在微小的电荷转移的,只是量很少,几乎不影响。所以厂家评判一个芯片是否满足要求,看的是其漏电等级是否在要求范围内。
对于写坏后的现象,厂家也不敢打包票就一定是什么样子的,所以对于EEPROM的擦写寿命,一定是要做严格控制的。
5.2 页写
就如上文所说,EEPROM是有页的概念的,虽然读数据的时候可以一帧把一整片存储的数据读出,但写入的时候,一帧最多只能写一页的数据,当写入的数据达到页末的时候,如果需要跨页写入,需要重新发一帧指令写入。那么问题来了,如果我就非要一帧写完,会发生什么事呢?就比如像24C128是64字节一页的,现在从0地址开始,一帧写入66个字节。此时IIC可以正常通信不会有任何异常显示,但当一帧65字节的数据写入后,前面64字节是正常写入的,但从第65个字节开始会将0地址的数据覆盖掉,第66字节的数据会将1地址的数据覆盖掉,以此类推循环覆盖。也就是写得再多的数据,也只会在这一页里循环覆盖,最终存储的数据,只有在这一帧发送完成后,在延时的时间内,EEPROM芯片自身对最终的数据进行存储。
那这里又引出另外一个问题,如果我用的一个16k的EEPROM,但写入的地址是17k,会发生什么事?答案是跟上面的现象类似,会循环从0地址开始算,即17k实际写入的是1k那个位置的地址。其实从地址二进制数上就可以看出来,当一个16k的EEPROM,其可读写的地址最大是0b 0011 1111 1111 1111,其有效地址位就是低14位,当数据再往上加1,比如0b 0100 0000 0000 0000,可以看到其低14位数据为0,即0地址。所以当使用EEPROM时,如果遇到有开头几个数据莫名地被修改时,请检查一下是否空间用超了。最好是在写入数据时,对写入的地址进行检查,用超时报错或反馈异常。
5.3 时序
如果使用单片机自带的硬件IIC,那可能不用太在意通信的时序,但如果是使用模拟IIC进行通信,那就得留意一下规格书里的几个时序时间是否满足了。
通过IO口进行翻转,需要留意SCL翻转的频率是否超过规格书里标称的最大频率,如果是,则需要调低翻转速率(在翻转过程增加延时)。
写入数据后,需要延时5ms,这段时间是用于给EEPROM实际将数据存储起来,如果写入后没延时就进行下一帧的读写操作,此时EEPROM不会作出应答。包括有些应用会拿EEPROM来做掉电前保存,那么掉电保持电量的时间需要把这个延时存储的时间考虑进来,否则在写入数据帧发送完成后,立即切断EEPROM电源,会导致数据实际未写入而丢失。延时的这个5ms因芯片厂家不同存在差异,像ATMEL是固定5ms,有些是根据供电电压不同,要求的延时时间也不同,目前最长有见到有10ms的,实际编写代码时需要翻阅对应厂家提供的规格书。
5.4 虚焊
玩嵌入式的,永远避不开的一个话题就是硬件,而硬件,最让人想不到的一些异常就是制程工艺。如果引脚虚焊,那经常表现出来就是功能不良,像VCC、SCL、SDA、A0~A2任一引脚虚焊,要么接触上可以正常读写,要么没接触上无法读写。但有一个引脚比较特殊,曾经遇到过GND引脚焊接不良的,其失效模式是数据可以正常读取,写入数据时EEPROM也可以正常的应答,但是掉电后数据不保存,也就是写入的数据并没有实际存储到EEPROM芯片中。从理论分析可能是因为芯片未接地,所以当需要存储消耗较大电流时,电流无法形成回路,导致数据无法存储。
5.5 干扰
这个可以说是嵌入式软件的一生之敌,电气干扰这东西,就是看不见、摸不着,时不时给你来一下,你还不一定能抓得到当时异常时出现的干扰。因为跟EEPROM通信的协议本身是不具备校验性的,不像Modbus协议有个CRC校验,所以当通信过程被干扰时,会出现很多你想象不到的异常。

就以上面的IIC通信时序图为例,假如现在有一个字节长度的干扰,这个干扰可以落在上面SDA的任意一个地方,让原本的位产生翻转,那么就会有以下几种情况:
1、落到起始位:因为IIC的时序要求,是先拉低SDA,再拉低SCL作为起始信号,如果干扰出现在起始位,则是SDA线该拉低时无法拉低,这样就会导致起始信号不生效,起始位延后。如果后面的IIC通信均正常,此时对于EEPROM来讲会丢一帧的数据。因为标准IIC协议中,SDA线上的数据翻转只能在SCL线为低电平的时候进行,也就是SCL为高电平时,SDA翻转的只有起始位和停止位,所以一旦起始位被干扰丢失,EEPROM识别到下一次起始只能是下一个完整帧。
2、落到设备地址:设备地址作为跟EEPROM通信的唯一ID,由硬件接线固定下来后是不可变更的,如果此时因干扰导致IIC通信的设备ID发生变化,则会导致设备不会应答,因此会在发送完设备ID后终止通信。
3、落到设备地址读写位:原本该写入数据的变成读数据,而原本要读取数据的,变成写入数据。
4、落到内存地址:EEPROM的读写,都是根据当前写入的内存地址为起始进行偏移,如果写入内存地址时被干扰导致出错,会造成读出错误的数据,或者将数据写入错误的位置,覆盖掉其他地址的数据。
5、落到数据段:当前地址段被写入错误的值,或读取出来错误的值。读取错误的还好,起码EEPROM内部存储的数值还是正确的,再次正常读取即可,但如果写入值被干扰成错误值,则会导致数据永久地丢失。
6、落到应答位:如果是写入数据,会让主机误以为EEPROM芯片未正确接收数据,触发错误处理(如重试、终止通信等);如果是读取数据,则会让EEPROM误以为主机未准备好接收数据,从而停止发送数据或进入错误状态。
- 预防措施
硬件:
1、写保护端口的使用,如果写保护端口由单片机控制,则可以控制在需要写入数据时,才拉低WP引脚进行数据写入,写完数据后拉高,这样可以防止上述提及的干扰出现在设备地址读写位,导致读数据变成写数据的情况。
2、单片机与EEPROM芯片应尽可能地靠近,即要让PCB上的SCL和SDA走线尽可能地短,且其围起来的面积尽可能地小。减少空间磁场的干扰。
3、可适当增加上拉电阻及滤波电容,增加抗干扰性。
软件:
1、每次写入数据时,回读进行数据确认,以保证写入的与读出的数据保持一致,从而有效地识别因干扰导致的数据写错。
2、当首次上电读取数据时,因为没有之前的数据作为参考,所以可以通过读取两次数据进行对比,来识别读取数据的正确性(因为干扰具有随机性,两次读取被干扰到同一个位置的数据,可能性极低)。如果是进行大批量的数据读取,为了节省空间,可在第一次读取数据后计算CRC,并暂存在RAM中,读取第二次数据后再计算一次CRC,跟首次的CRC值进行对比,如果一致,则说明读取的数据是可靠的。
3、当某种情况下,EEPROM芯片处于非空闲状态,而单片机处于空闲状态时,需要先将EEPROM芯片进行复位,再进行正常操作。
5.6 芯片损坏
EEPROM本体出厂损坏的案例比较少,直至当前为止本人就发现过一例,每两页数据中就有一个字节的相邻两个位存在异常(例:第1页第7个字节,第3页第7个字节,第5页第7个字节……),并且该问题通过全片写0xFF和全片写0是无法识别出来的,需要写入0xAA(0b 1010 1010)或0x55(0b 0101 0101)才能识别。为了防止出现EEPROM原厂出货的芯片存在缺陷,最好是在生产时对芯片进行一次全片写入并读取检验,即全片写0xAA,读回判断,再全片写0x55,再读回判断,两次均正常,则可认为芯片正常。
六、相关链接
更多推荐



所有评论(0)