某台工业数据记录仪要连续写入 32MB 的波形数据,调试时发现写到一半就卡住——不是代码问题,是 Flash 的页编程时间没算对。这种场景下,一颗 256Mbit 的 NOR Flash 其实是系统里最容易被低估的器件。规格书上标着 800µs 的页编程时间,但实际项目里如果没配好 SPI 时序,或者忽视了 Quad I/O 模式下的引脚 mux 映射,性能就出不来了。本文拿 Johanson Technology 的 IS25LP256D-JMLE-TY 当案例,把 NOR Flash 在嵌入式系统里的几个关键工程点拆开来说。
NOR Flash 的工作原理与内部结构
NOR Flash 的核心是浮栅晶体管阵列,每个存储单元由控制栅、浮栅、源极和漏极组成。写操作时通过沟道热电子注入往浮栅里灌电荷,擦除时用 Fowler-Nordheim 隧穿把电荷抽走。为什么叫 NOR?因为其单元阵列结构类似 NOR 逻辑门—每个 bit 线对应多个字线的并联,所以读取时能按字节随机访问,这正是 NOR 与 NAND 最大的区别。
IS25LP256D-JMLE-TY 的组织结构是 32M x 8,也就是 256Mbit 拆成了 32768 个 page(每个 page 256 字节),再分成 512 个 sector(每个 sector 4KB)和 4096 个 block(每个 block 64KB)。实际项目里最常用的是 sector 擦除(60ms 典型值)和 page 编程(800µs 典型值)。NOR 的擦写速度比 SRAM 慢,但读取延迟低——166MHz 时钟下四线模式的理论吞吐能到 83MB/s,这对 code shadow 和参数存储足够了。
核心参数解读:时钟频率、供电范围与温度等级
| 参数名 | 数值 | 工程意义说明 |
|---|---|---|
| Memory Size | 256Mbit | 约 32MB 容量,适合存放中规模固件 + 配置参数 |
| Memory Interface | SPI - Quad I/O, QPI, DTR | 支持标准 SPI 和四线模式,DTR 可双倍数据率传输 |
| Clock Frequency | 166 MHz | 四线模式下理论读取带宽 ≈ 83MB/s,匹配主流 MCU QSPI 控制器 |
| Supply Voltage | 2.3V ~ 3.6V | 兼容 3.3V 和 2.5V 逻辑系统,低于 2.3V 需考虑电平转换 |
| Operating Temperature | -40°C ~ 105°C | 扩展工业级,覆盖 85°C 以上散热受限场景,如电机驱动器 |
| Write Cycle Time - Page | 800µs | 每页 256 字节,连续写多页时需预留 800µs 等待时间 |
166MHz 这个频率很关键。市面上不少 QSPI Flash 标称 133MHz,但实际上需要拉长走线或增加驱动强度才能跑稳。这颗料的 datasheet 里给的 166MHz 是在 1.8V I/O 下的条件,如果你用的是 3.3V 供电,走线长度控制在 50mm 以内基本不需要串阻。页编程时间 800µs 是典型值,温度跑低时可能缩到 500µs 左右,但实测下来建议按 datasheet 的最大值(3ms)做超时处理,否则 -40°C 低温下可能出现偶发编程失败。
供电范围 2.3V 到 3.6V 意味着它可以直连 2.5V 或 3.3V 的系统。需要注意的是,如果 MCU 的 QSPI IO 电压是 1.8V,这颗料不兼容——它没有独立的 VccIO 引脚。非要混用的话需要加电平转换或分压电阻,但那样读写时序就受影响了。
选型时的引脚兼容性与二供判断
NOR Flash 的封装引脚分布其实有 JEDEC 规范,但各家在 Quad IO 模式下对 WP# 和 HOLD# 的处理不一样。IS25LP256D-JMLE-TY 用的是 16-SOIC(7.50mm 宽体),引脚顺序和 Macronix 的 MX25L25645G 以及 Winbond 的 W25Q256JV 完全一致。如果你现在在做选型,可以直接拿 Pin-to-Pin 兼容矩阵来对照:只要确认 HOLD# 引脚在系统里可以接高电平(或由 MCU 的 GPIO 控制),这三颗料就是直替关系。
具体替换时要注意一个细节:这家 Johanson Technology 的芯片在 QPI 模式下,默认的 dummy cycle 设置可能和其他家不同。手册上没明说的是,IS25LP256D 上电后的状态默认是 SPI 模式(非 QPI),所以代码里初始化时必须先发 QPI 使能指令(38h)才能切到四线模式。如果你从 W25Q 切过来,可能会踩到这个坑——初始化序列不完全一致。
对于国产替代评估,目前 NOR Flash 市场里兆易创新(GD25Q256D)和博通集成(BK25Q256)都有相似容量的产品,引脚定义基本兼容,但温度等级通常只有 -40~85°C。105°C 扩展工业级的选择目前仍然集中在原厂阵营,如果你需要车规级(AEC-Q100),那就得直接找 Winbond 或 Macronix 的对应型号了。
典型应用场景与 PCB 布局要点
这颗 256Mbit NOR Flash 最常见的用法是给 MCU 做 exec-in-place(XIP)存储器,比如在工业以太网网关里存放协议栈和固件。因为 NOR 的随机读取延迟低,CPU 可以直接在 Flash 上跑代码,不需要先把固件加载到 RAM。实际项目里遇到过一个问题:如果 Flash 的 SPI 走线和以太网 PHY 的时钟线平行走 50mm 以上,串扰会造 QSPI 数据线偶尔闪过错误的比特。解决办法是 Flash 和 MCU 之间的连接尽量用星型拓扑,走线间距拉大到 3 倍线宽,并且所有 Quad IO 线保持等长。
另一个场景是做 FPGA 的配置存储器。166MHz 的读取带宽足够给大部分中等规模的 FPGA(如 Xilinx Spartan-7)在几十毫秒内加载 bitstream。但是要注意 FPGA 上电初期 Vcc 可能还没稳定到 2.3V,所以 Flash 的 CS# 必须用上拉电阻接高电平,否则配置过程中 Flash 可能会因为欠压而输出乱码。经验上,这个上拉电阻选 10kΩ 就够,太小的阻值会增加待机功耗。
对于电池供电的 IoT 设备,这颗料的待机电流约 30µA(典型值),相比同类产品偏低。但如果你在深度睡眠时需要保持 Flash 内容,就不能完全断电,必须靠 MCU 的 GPIO 控制 Vcc 或 CS# 来满足更低功耗——不过那样会丢失 Flash 的 Write Protect 状态,重新上电后需要重新配置保护区。
常见的工程坑与故障排查
最常见的问题是烧录失败。遇到过一块板子在产线上写固件,前 50 片正常,第 51 片开始报擦除超时。排查后发现是编程器设置的 Vcc 电压是 3.3V,但电源模块在批量时波纹偏大(峰峰值到了 200mV),导致 Flash 供电偶尔低于 2.3V。解决办法是在 Flash 的 Vcc 引脚附近加一颗 100nF + 10µF 的退耦电容,并且保证电容的 ESL 要低——普通 MLCC 的 0805 封装就够了,但别用铝电解。
第二个坑跟 DTR(Double Transfer Rate)模式有关。IS25LP256D 支持 DTR 模式下在时钟的上升沿和下降沿都采样数据,看起来能翻倍带宽。但实测发现,如果 MCU 的 QSPI 控制器不支持调整采样相位(比如 STM32H7 的 QUADSPI 需要配置 Sample Shift),那 DTR 模式下的 setup/hold 余量会不足 1ns,导致数据错误。解决办法要么降回 STR 模式(单沿采样),要么在 PCB 上给 Flash 的 CLK 线串接一个 22Ω 电阻来微调延迟。
还有一个容易忽略的点:电源上电顺序。如果 Flash 的 Vcc 比 MCU 的 Vdd IO 后上电,MCU 的 GPIO 在初始化期间可能输出不确定电平,这会让 Flash 误判为非法命令并锁死。保险的做法是把 Flash 的 CS# 用 10kΩ 电阻上拉到 Vcc,同时 MCU 的 GPIO 在配置为输出之前保持高阻态。
常见误区:别再跟 NAND Flash 比耐擦写次数
有些工程师第一次用 NOR Flash 时会拿 NAND 的擦写循环指标(通常 10 万次以上)来对比,然后觉得 NOR 的 10 万次太低了。这是一个误区。NOR Flash 的读写机制决定了它的单元寿命大约是 10 万次(部分工业级型号标 20 万次),但这跟应用场景绑定的:如果只是存固件(写一次读十年),10 万次完全够用;但如果你拿它当实时日志缓冲区(每秒写一次),那确实一年就磨废了。对于后一种情况,正确的做法是用外部的 EEPROM 或 FRAM,或者做 wear-leveling 算法。
另外,有些人看到 166MHz 就以为所有读写操作都能跑这个频率。实际上,页编程和擦除操作的速度并不依赖时钟频率,它们是由内部的高压电荷泵和擦写算法决定的。166MHz 只影响连续读取的吞吐量。手册里写的 800µs 页编程时间,在任何时钟频率下都是差不多的——除非你启用了 Write Enable Latch 优化。
收尾说一句:如果你正在做一颗需要 XIP 且温度环境恶劣的产品,这颗 Johanson Technology 的 记忆芯片值得仔细看一遍 datasheet 里的 AC 时序表,特别是 T_CSH(CS# deselect hold time)这个参数——它在不同读写模式下差别很大,而且直接影响多块连续读取的正确性。