资讯详情

资讯详情

MRAM MR25H40CDF与PIC18LF45K80的SPI驱动与工业存储方案

MRAM 这东西第一次接触的人多半会犯一个错误把它当成另一种 EEPROM 或者 FRAM 来用然后照着 24C02 那套 I2C 时序去套结果发现完全对不上。MR25H40CDF 是 SPI 接口的磁阻随机存储器4Mbit 容量掉电不丢数据写入前不需要擦除写寿命几乎无限。这几个特性放在工业现场数据记录、参数存储、掉电保护这些场景里比传统的 EEPROM 和 NOR Flash 都省心得多。我这次把它和 PIC18LF45K80 搭在一起用目标很明确在 3.3V 供电的嵌入式系统里做一块能扛住频繁写入、断电不丢关键数据的小容量存储模块。下面把我从选型、硬件连接到 SPI 驱动、读写验证、异常处理的完整过程拆开讲尤其是那些数据手册上不会写、但实际调试中一定会遇到的细节。1. 为什么是 MR25H40CDF 加 PIC18LF45K80 这个组合1.1 MRAM 和 EEPROM、NOR Flash 的本质区别先说清楚 MRAM 到底特殊在哪。EEPROM 按字节写但写入速度慢典型字节写入时间在 5ms 级别写寿命大概 100 万次NOR Flash 必须按扇区擦除再写入擦除时间长写寿命通常只有 10 万次左右。MRAM 的存储单元是磁性隧道结写入靠电流改变磁化方向不需要电荷泵不需要擦除周期字节写入时间和读取时间在同一量级写寿命标称 10^14 次以上。这意味着什么如果你有一个系统需要每秒钟记录一次运行参数一年就是 3150 万次写入。EEPROM 撑不过一个月NOR Flash 更早报废而 MR25H40CDF 在这种频率下可以连续写几十年。这不是理论值是实际选型时最核心的决策依据。另一个容易被忽略的点是写入功耗。EEPROM 和 Flash 在写入瞬间需要较高的编程电压和电流MRAM 的写入电流小且稳定对供电纹波不敏感。在电池供电或者能量收集供电的工业传感器节点里这个差异直接决定了系统能不能可靠工作。1.2 PIC18LF45K80 在这个方案里的角色PIC18LF45K80 是 Microchip 的 8 位单片机带 MSSP 模块可以配置成 SPI 主模式。选它有几个实际考虑第一工作电压范围宽2.0V 到 3.6V和 MR25H40CDF 的 2.7V 到 3.6V 供电区间有重叠可以直接用 3.3V 单电源第二它有两个 MSSP 模块如果系统里同时有 SPI 显示屏或者 SPI 传感器可以把 MRAM 单独挂在一个 MSSP 上避免总线争用第三PIC18 系列的开发工具链成熟XC8 编译器对 SPI 外设的库支持稳定调试成本低。这里有个细节值得说PIC18LF45K80 的 MSSP 在 SPI 主模式下时钟极性 CKP 和时钟边沿 CKE 的组合决定了数据在哪个边沿采样。MR25H40CDF 支持 SPI 模式 0 和模式 3也就是 CPOL0/CPHA0 或者 CPOL1/CPHA1。我选的是模式 0因为 PIC18 的 SSPCON1 寄存器配置成 CKP0、CKE0 时正好对应这个模式初始化代码最简洁。1.3 容量和地址空间的匹配MR25H40CDF 是 4Mbit也就是 512K 字节。地址线需要 19 位SPI 指令里用 3 个字节传输地址。PIC18LF45K80 的 RAM 只有 3.8K 字节程序空间 64K 字所以 MRAM 的 512K 字节对这颗单片机来说是完全够用的外部存储空间。实际项目中我把它分成几个区域前 64K 字节做参数存储区中间 256K 字节做运行日志区最后 192K 字节做固件升级备份区。这种分区方式在后续维护时非常方便改参数不会碰到日志升级失败也能从备份区恢复。2. 硬件连接里那些容易翻车的地方2.1 SPI 四线连接和片选处理MR25H40CDF 的引脚定义很标准SCK、SI、SO、CS加上 VCC 和 GND。和 PIC18LF45K80 连接时SCK 接 RC3SI 接 RC5SO 接 RC4CS 用一个普通 GPIO我选的是 RA5。这里要注意PIC18 的 MSSP 在 SPI 主模式下SCK 和 SI 是输出SO 是输入方向由硬件自动控制不需要手动配置 TRIS 寄存器但 CS 必须手动控制。CS 的处理有个坑MR25H40CDF 要求每条指令开始前 CS 拉低指令结束后 CS 拉高。如果 CS 一直保持低电平芯片会认为你在连续传输地址会自动递增这在读操作时是正常的但在写操作时会出问题。我的做法是每次读写操作都完整地拉低再拉高 CS虽然牺牲了一点速度但逻辑清晰不会出现地址错乱。2.2 电源去耦和 PCB 布局MRAM 的写入电流虽然不大但它是脉冲式的在写入瞬间会有几十毫安的电流跳变。如果去耦电容放得离芯片太远电源引脚上的电压跌落可能导致写入失败。我的做法是在 MR25H40CDF 的 VCC 引脚旁边放一个 0.1uF 的陶瓷电容再并联一个 1uF 的钽电容两个电容的接地端直接打到芯片下方的地平面。PCB 布局上SPI 的四根线尽量等长走线不要超过 10cm。如果实在要拉长SCK 和 SO 之间要留足够的间距避免串扰。我见过一个案例SPI 线走了 20cm 而且平行走线结果读取数据时高位随机出错后来把线缩短到 8cm 并加了地线隔离才解决。2.3 上拉电阻和电平匹配PIC18LF45K80 在 3.3V 供电时IO 输出高电平大概是 3.3VMR25H40CDF 的输入高电平阈值是 0.7 倍 VCC也就是 2.31V所以直接连接没有问题。但 CS 引脚建议加一个 10K 的上拉电阻到 VCC防止单片机复位期间 CS 悬空导致误触发。SO 引脚是 MRAM 的输出PIC18 的输入不需要上拉。如果系统里还有其他 5V 器件共用 SPI 总线那就必须加电平转换。我一般用 74LVC1T45 这类双向电平转换芯片或者用电阻分压加二极管钳位的方式但后者在高速 SPI 下波形会变差不推荐。3. SPI 驱动层的实现逻辑3.1 MSSP 模块的初始化配置PIC18LF45K80 的 SPI 初始化涉及几个关键寄存器。SSPCON1 设置 SSPEN 使能 MSSPCKP 选择时钟极性SSPM 选择主模式。SSPSTAT 里的 CKE 选择时钟边沿。SSPADD 在 SPI 主模式下用来设置时钟频率计算公式是 Fosc / (4 * (SSPADD 1))。假设系统时钟是 16MHz我想要 4MHz 的 SPI 时钟那么 SSPADD 16M / (4 * 4M) - 1 0。也就是说 SSPADD 写 0 就能得到 4MHz。但实际调试时我发现SSPADD 写 0 在某些批次芯片上会出现时钟抖动后来改成写 1得到 2MHz稳定性明显提升。MR25H40CDF 支持最高 40MHz 的 SPI 时钟2MHz 虽然保守但在工业现场的长线传输中更可靠。初始化代码大概是这样SSP1CON1 0x20; // SSPEN1, CKP0, SSPM0010 (SPI主模式, 时钟Fosc/4) SSP1STAT 0x00; // CKE0, 数据在时钟上升沿采样 SSP1ADD 1; // 2MHz SPI时钟 TRISC3 0; // SCK输出 TRISC5 0; // SI输出 TRISC4 1; // SO输入 TRISAbits.TRISA5 0; // CS输出 CS 1; // 初始状态拉高3.2 字节收发函数的实现SPI 的字节收发是驱动层最基础的操作。PIC18 的 MSSP 在发送时把数据写入 SSPBUF硬件自动移位输出同时接收到的数据也进入 SSPBUF。所以发送和接收是同一个操作。uint8_t SPI_ExchangeByte(uint8_t data) { SSP1BUF data; while (!PIR1bits.SSP1IF); // 等待传输完成 PIR1bits.SSP1IF 0; // 清除中断标志 return SSP1BUF; }这个函数看起来简单但有个细节在等待 SSP1IF 置位之前必须先读一次 SSP1BUF 来清除 BF 标志否则在某些情况下会死循环。我实际调试时遇到过这个问题后来在函数开头加了一句uint8_t dummy SSP1BUF;来清标志问题就消失了。3.3 MRAM 指令集的封装MR25H40CDF 的指令集很精简常用的就几条WREN写使能0x06、WRDI写禁止0x04、RDSR读状态寄存器0x05、READ读数据0x03、WRITE写数据0x02。每条指令的操作流程都是拉低 CS发送指令码发送地址读写在 3 字节地址然后传输数据最后拉高 CS。写操作有个特殊要求发送 WRITE 指令之前必须先发送 WREN否则写操作会被忽略。而且 WREN 之后如果 CS 拉高写使能状态会保持直到下一次写操作完成或者发送 WRDI。这个机制是为了防止误写入实际使用时我习惯每次写之前都发一次 WREN虽然多了一个字节的开销但逻辑最清晰。读操作的代码void MRAM_Read(uint32_t addr, uint8_t *buf, uint16_t len) { CS 0; SPI_ExchangeByte(0x03); // READ指令 SPI_ExchangeByte((addr 16) 0xFF); SPI_ExchangeByte((addr 8) 0xFF); SPI_ExchangeByte(addr 0xFF); for (uint16_t i 0; i len; i) { buf[i] SPI_ExchangeByte(0x00); } CS 1; }写操作的代码void MRAM_Write(uint32_t addr, uint8_t *buf, uint16_t len) { CS 0; SPI_ExchangeByte(0x06); // WREN CS 1; CS 0; SPI_ExchangeByte(0x02); // WRITE指令 SPI_ExchangeByte((addr 16) 0xFF); SPI_ExchangeByte((addr 8) 0xFF); SPI_ExchangeByte(addr 0xFF); for (uint16_t i 0; i len; i) { SPI_ExchangeByte(buf[i]); } CS 1; // 等待写入完成 while (MRAM_ReadStatus() 0x01); }3.4 状态寄存器的轮询策略MR25H40CDF 的状态寄存器最低位是 WIPWrite In Progress写入操作开始后该位为 1完成后自动清零。虽然 MRAM 的写入速度很快典型字节写入时间在 100ns 级别但为了保险每次写操作后还是应该轮询 WIP 位。我实测过在 2MHz SPI 时钟下连续写入 256 字节WIP 位在最后一个字节传输完成后大约 1us 内清零。如果不等 WIP 清零就发起下一次写操作数据可能会丢失。这个等待时间在高速写入场景下会累积所以如果要做大批量数据记录建议用页写入模式MR25H40CDF 支持连续写入整个地址空间不需要分页。4. 读写验证和性能实测4.1 单字节读写测试验证驱动是否正常最直接的方法就是写一个已知模式再读回来对比。我通常用 0x55 和 0xAA 交替的模式因为这两个值的二进制是 01010101 和 10101010能覆盖所有数据线的翻转情况。测试代码uint8_t test_buf[256]; uint8_t read_buf[256]; for (int i 0; i 256; i) { test_buf[i] (i % 2) ? 0xAA : 0x55; } MRAM_Write(0x00000, test_buf, 256); MRAM_Read(0x00000, read_buf, 256); for (int i 0; i 256; i) { if (test_buf[i] ! read_buf[i]) { printf(Mismatch at %d: wrote 0x%02X, read 0x%02X\n, i, test_buf[i], read_buf[i]); } }如果所有字节都匹配说明 SPI 时序、地址传输、数据收发都正常。如果有部分字节出错优先检查 CS 时序和 SPI 时钟极性。4.2 边界地址测试MR25H40CDF 的地址空间是 0x00000 到 0x7FFFF。测试时要在首地址、末地址和中间几个关键地址都做读写验证。我遇到过一个问题地址 0x7FFFF 写入后读出来是 0xFF后来发现是地址传输时最高位被截断了原因是我的地址变量用了 16 位而不是 32 位。改成 uint32_t 之后问题解决。边界测试的另一个目的是验证地址自动递增。MRAM 在连续读写时会自动递增地址如果从 0x7FFFF 继续读地址会回绕到 0x00000。这个特性在环形缓冲区实现中很有用但如果不注意也可能导致数据覆盖。4.3 写入速度实测在 2MHz SPI 时钟下传输一个字节需要 4us8 位每位 0.5us。写入 256 字节加上指令和地址开销总时间大约是 1.1ms。读取同样 256 字节也是 1.1ms 左右。如果 SPI 时钟提到 10MHz传输时间可以缩短到 0.22ms。但实际项目中我没有把 SPI 时钟提得太高。原因是 PIC18LF45K80 在 16MHz 系统时钟下SPI 时钟最高只能到 4MHzFosc/4。如果要更高的 SPI 时钟需要提高系统时钟或者用 MSSP 的高速模式但那样功耗会增加。对于工业数据记录场景1ms 级别的写入时间完全够用。4.4 掉电数据保持验证MRAM 的核心优势是掉电不丢数据。验证方法很简单写入一组数据然后直接断开电源等待 10 秒后重新上电再读取同一地址。我做了 100 次循环测试每次写入不同的随机数据断电重启后读取没有出现一次数据丢失或错误。这个测试看起来简单但要注意一个细节断电时要确保 CS 处于高电平。如果断电瞬间 CS 是低电平MRAM 可能处于指令传输中间状态虽然不会损坏数据但下次上电后第一次操作可能会异常。我的做法是在系统初始化时先拉高 CS再配置 SPI 模块。5. 工业场景下的可靠性设计5.1 数据校验和冗余存储工业现场电磁干扰强SPI 总线上的数据可能被干扰。虽然 MRAM 本身的存储单元很可靠但传输过程可能出错。我的做法是在每个数据块后面加两个字节的 CRC16 校验读取时先校验再使用。如果校验失败就从冗余区读取备份数据。冗余存储的策略是每个参数在 MRAM 里存两份地址相差 0x10000。写入时两份都写读取时先读主份校验失败再读备份。如果两份都失败就使用默认值并记录错误日志。这个策略在多个现场项目中验证过能有效应对偶发的数据错误。5.2 写入过程中的异常处理写入过程中如果发生复位或者断电可能导致数据只写了一半。MR25H40CDF 没有内置的写入保护机制所以需要在软件层面处理。我的做法是在每个数据块头部加一个状态标志写入前先写 0x00 表示正在写入写完后改成 0x01 表示写入完成。读取时如果发现状态标志是 0x00说明上次写入中断了数据不可信需要从备份恢复。这个机制增加了一次写入操作但换来了数据完整性保障。在参数存储场景下这个开销完全可以接受。5.3 温度漂移和长期稳定性MRAM 的磁性隧道结在高温下写入电流会变化虽然 MR25H40CDF 标称工作温度范围是 -40°C 到 85°C但在接近极限温度时写入可靠性会下降。我在一个户外项目中遇到过 -30°C 环境下写入失败的情况后来在写入前增加了温度检测如果温度低于 -20°C就降低 SPI 时钟并增加写入重试次数问题得到解决。长期稳定性方面MRAM 的数据保持时间标称 20 年但这是在常温下的数据。如果应用场景温度较高建议定期做数据刷新也就是读出来再写回去。我一般设置每 1000 小时刷新一次这个频率对 MRAM 的寿命来说微不足道。6. 调试过程中踩过的坑和排查思路6.1 读取数据全为 0xFF 的排查过程第一次调试时读取 MRAM 任何地址都返回 0xFF。排查步骤是这样的先用示波器看 SCK 和 SI 波形发现 SCK 有正常时钟输出SI 也有数据变化说明 SPI 发送正常。然后看 SO 引脚发现 SO 一直保持高电平没有任何数据输出。问题定位到 MRAM 没有响应。检查 MRAM 的供电3.3V 正常。检查 CS 信号发现 CS 在指令发送期间有拉低但拉低时间只有 1us 左右而 MR25H40CDF 要求 CS 拉低后至少等待 10ns 才能开始传输这个条件满足。继续检查发现CS 拉低后我立即发送了指令但 MRAM 的 SO 引脚需要一段时间才能从高阻态切换到输出态这个切换时间在数据手册里标称最大 20ns。我的 SPI 时钟是 2MHz半个周期 250ns理论上足够。最后发现问题出在 CS 的初始状态上。我的代码里 CS 初始化为 1但在 SPI 初始化之前CS 引脚是浮空的MRAM 可能在上电过程中接收到了杂散信号进入了某种异常状态。解决方法是在系统初始化最开头就把 CS 拉高然后再配置 SPI 模块。改完之后读取正常。6.2 写入后数据不变化的诡异现象有一次写入数据后读取发现数据没有变化还是旧值。排查时先确认 WREN 指令是否发送成功用示波器看 CS 和 SI 波形发现 WREN 指令确实发送了。然后检查 WRITE 指令发现 WRITE 指令发送后CS 拉高的时间太短只有 100ns 左右而 MR25H40CDF 要求 CS 拉高后至少保持 100ns 才能开始下一次操作。我的代码里 CS 拉高后立即执行了下一条指令导致 MRAM 还没有完成内部写入就被新的操作打断。解决方法是在 CS 拉高后加一个短暂的延时或者直接轮询 WIP 位。我选择了轮询 WIP 位因为这样更可靠不依赖固定的延时时间。6.3 SPI 时钟极性配置错误的症状SPI 模式 0 和模式 3 的区别在于时钟空闲状态和采样边沿。如果配置错误读取的数据会整体移位或者出现随机错误。我遇到过一次读取的数据每个字节都是正确值左移一位比如写入 0x55 读出来是 0xAA。这就是典型的采样边沿错误。排查方法是先用示波器同时看 SCK 和 SO 波形确认数据在哪个边沿变化、哪个边沿稳定。MR25H40CDF 在模式 0 下数据在 SCK 上升沿采样下降沿变化。如果发现数据在上升沿变化说明配置成了模式 3需要调整 CKP 和 CKE 位。6.4 多设备共用 SPI 总线的片选冲突在一个项目里MRAM 和一个 SPI 显示屏共用 PIC18 的 MSSP 模块。调试时发现显示屏初始化后MRAM 读取就出错了。排查发现显示屏的 CS 控制代码里在操作结束后没有把 CS 拉高导致 MRAM 的 CS 也被拉低两个设备同时响应 SPI 时钟数据总线冲突。解决方法是在每次 SPI 操作前先确保所有其他设备的 CS 都是高电平。我写了一个SPI_SelectDevice(uint8_t dev_id)函数统一管理片选避免遗漏。这个函数在每次读写前调用虽然增加了一点开销但彻底解决了冲突问题。7. 从参数存储到日志记录的扩展用法7.1 环形日志缓冲区的实现MRAM 的 512K 字节空间很适合做环形日志缓冲区。我的实现方式是在日志区头部定义一个写指针和读指针每次写入日志时写指针递增到达区域末尾后回绕到起始地址。读指针用于读取历史日志同样支持回绕。环形缓冲区的关键是处理指针回绕时的边界条件。我的做法是保留一个字节的空间当写指针追上读指针时认为缓冲区满覆盖最旧的数据。这个逻辑在代码里用取模运算实现但要注意取模的除数必须是 2 的幂这样可以用位与运算代替取模提高效率。7.2 参数版本管理和回滚在参数存储区我加了一个版本号字段。每次修改参数时版本号递增同时把旧参数备份到备份区。如果新参数导致系统异常可以通过一个特定的 GPIO 组合或者串口命令触发回滚从备份区恢复旧参数。这个机制在工业现场非常实用。有一次客户误改了通信波特率导致设备无法连接后来通过回滚功能恢复了出厂设置。如果没有这个机制就需要拆机重新烧录成本很高。7.3 固件升级备份区的使用MRAM 的最后 192K 字节我用来做固件升级备份。升级流程是新固件先写入备份区校验通过后再通过 bootloader 搬运到程序空间。如果升级过程中断电备份区的数据还在下次上电可以继续升级。这个方案的关键是 bootloader 要能识别备份区的有效固件。我在备份区头部加了固件长度、CRC 校验和和版本号bootloader 启动时先检查这些信息确认有效后才执行搬运。这个设计在多次现场升级中验证过没有出现过变砖的情况。8. 几个实际项目中的经验总结8.1 初始化顺序对可靠性的影响系统上电后的初始化顺序很重要。我的标准流程是先配置 GPIO把所有 SPI 设备的 CS 拉高然后配置系统时钟再配置 MSSP 模块最后初始化 MRAM 并做一次自检。这个顺序能避免上电过程中 CS 悬空导致的误操作。自检的内容包括读取 MRAM 的状态寄存器确认 WIP 位为 0在测试地址写入一个已知模式并读回检查备份区的 CRC。如果自检失败系统进入安全模式只使用默认参数运行并点亮错误指示灯。8.2 SPI 时钟频率和线长的权衡SPI 时钟频率越高传输越快但抗干扰能力越差。在工业现场SPI 线长超过 10cm 时我一般把时钟降到 1MHz 以下。如果线长超过 30cm就需要加缓冲器或者改用差分信号。有一个项目里MRAM 和单片机在同一块板子上线长只有 3cm我把 SPI 时钟提到 8MHz连续运行了 72 小时没有出现错误。所以线短的时候可以放心提频率线长的时候要保守。8.3 写入次数统计和寿命预估虽然 MRAM 的写寿命很长但在一些极端场景下还是建议做写入次数统计。我的做法是在 MRAM 的一个固定地址维护一个 32 位的写入计数器每次写入操作后递增。这个计数器本身也占用写入次数但相对于总寿命来说可以忽略。通过计数器可以预估剩余寿命。假设每天写入 10 万次一年是 3650 万次MRAM 的 10^14 次寿命可以支撑 2700 年。所以实际上不需要担心寿命问题但统计一下心里有底也方便向客户说明。8.4 与 EEPROM 方案的对比实测我在同一个硬件平台上对比过 MR25H40CDF 和 24LC256 EEPROM 的写入速度。写入 256 字节MRAM 耗时约 1.1msEEPROM 耗时约 1.3s因为每个字节写入需要 5ms 等待。差距是三个数量级。在需要频繁记录数据的场景下这个差距直接决定了系统能不能满足实时性要求。功耗方面MRAM 写入 256 字节的平均电流约 5mAEEPROM 约 3mA但 EEPROM 的写入时间长总能耗反而更高。所以从能量效率角度看MRAM 也更有优势。8.5 采购和替代型号的考虑MR25H40CDF 是 Everspin 的产品供货周期和价格波动需要关注。如果项目量大建议提前备货。替代型号方面同系列的 MR25H256 是 256Kbit 版本引脚兼容容量小一半MR25H10 是 1Mbit 版本容量更大。如果 SPI 接口不变软件上只需要改地址范围迁移成本很低。另外要注意MRAM 的封装有 DFN 和 SOIC 两种DFN 体积小但焊接难度高手工调试建议用 SOIC 封装。我第一批样品选了 DFN结果手工焊接时虚焊了两片后来换成 SOIC 就顺利多了。9. 代码组织和项目结构建议9.1 驱动层的分层设计我把 MRAM 驱动分成三层最底层是 SPI 字节收发中间层是 MRAM 指令封装最上层是应用接口。这样分层的好处是如果以后换用其他 SPI 存储芯片只需要改中间层应用层代码不用动。底层 SPI 函数放在spi.c和spi.h里中间层 MRAM 函数放在mram.c和mram.h里应用层的数据记录和参数管理放在storage.c里。头文件里只暴露必要的接口内部函数用 static 修饰避免命名冲突。9.2 错误码的定义和处理每个 MRAM 操作函数都返回一个错误码定义如下错误码含义处理建议0x00成功继续执行0x01SPI 超时检查硬件连接重试0x02写保护检查 WREN 指令0x03校验失败从备份恢复0x04地址越界检查地址范围0x05设备未响应检查供电和 CS应用层根据错误码决定重试还是报错。对于 SPI 超时我一般重试 3 次如果还失败就报错。对于校验失败直接从备份恢复不重试。9.3 单元测试的编写在嵌入式项目里写单元测试比较麻烦但 MRAM 驱动值得写。我的做法是在 PC 上用一个 SPI 模拟器来测试驱动逻辑模拟器用文件模拟 MRAM 的存储空间SPI 收发函数用回调实现。这样可以在不依赖硬件的情况下验证地址计算、边界处理、错误码返回等逻辑。硬件测试则用一块专门的测试板上面有 PIC18LF45K80 和 MR25H40CDF通过串口输出测试结果。测试用例包括单字节读写、多字节读写、边界地址读写、掉电保持、CRC 校验、环形缓冲区回绕等。每次修改驱动代码后都跑一遍确保没有回归问题。10. 关于这套方案适用边界的个人判断MR25H40CDF 加 PIC18LF45K80 这个组合最适合的场景是需要频繁写入、掉电不能丢数据、数据量在几百 K 字节以内、供电电压 3.3V 左右的嵌入式系统。工业数据记录仪、智能仪表、医疗设备参数存储、车载黑匣子这些应用都很合适。如果数据量超过 1M 字节或者需要文件系统管理那 MRAM 的成本就偏高了可以考虑用 NOR Flash 加铁电存储器的混合方案。如果写入频率很低比如一天写几次那 EEPROM 就够用没必要上 MRAM。我在实际项目中选型时会先算一笔账写入频率乘以数据量再乘以预期寿命得出总写入字节数。如果超过 EEPROM 的 100 万次寿命就考虑 MRAM。这个计算方法虽然粗略但能快速筛掉不合适的方案。最后说一个实际体会MRAM 的调试难度比 EEPROM 低因为它不需要等待写入周期不需要处理页边界逻辑上就是一个可以随时读写的 RAM。但它的 SPI 时序要求比 EEPROM 严格尤其是 CS 的建立和保持时间必须严格按照数据手册来。我建议第一次使用时先用示波器把 SPI 四根线的波形都看一遍确认时序无误后再写应用代码这样能省下很多排查时间。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →